[openchrome-devel] drm-openchrome: Branch 'drm-next-5.5' - 108 commits - arch/ia64/include Documentation/devicetree/bindings drivers/char/agp drivers/firmware/qcom_scm-32.c drivers/firmware/qcom_scm-64.c drivers/firmware/qcom_scm.c drivers/firmware/qcom_scm.h drivers/gpu/drm drivers/soc/qcom include/linux/agpgart.h include/linux/miscdevice.h include/linux/qcom_scm.h include/soc/qcom MAINTAINERS

Kevin Brace kevinbrace at kemper.freedesktop.org
Wed Dec 11 22:59:09 UTC 2019


 Documentation/devicetree/bindings/display/msm/gmu.txt    |   51 +
 Documentation/devicetree/bindings/display/msm/mdp5.txt   |    2 
 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml   |   96 +++
 MAINTAINERS                                              |    1 
 arch/ia64/include/asm/agp.h                              |    4 
 drivers/char/agp/frontend.c                              |    3 
 drivers/char/agp/generic.c                               |   12 
 drivers/firmware/qcom_scm-32.c                           |   52 +
 drivers/firmware/qcom_scm-64.c                           |   12 
 drivers/firmware/qcom_scm.c                              |   53 +
 drivers/firmware/qcom_scm.h                              |    9 
 drivers/gpu/drm/Kconfig                                  |    1 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c         |   15 
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c                  |    4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c           |   17 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h           |    1 
 drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c                  |   10 
 drivers/gpu/drm/amd/amdgpu/cik.c                         |    7 
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c                   |  178 +-----
 drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c                    |    2 
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c                    |   40 -
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c                    |   40 -
 drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c                 |   19 
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c                   |    3 
 drivers/gpu/drm/amd/amdgpu/vi.c                          |    7 
 drivers/gpu/drm/amd/amdkfd/Kconfig                       |    2 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c |    3 
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c       |   19 
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c    |   74 ++
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c               |    9 
 drivers/gpu/drm/amd/powerplay/arcturus_ppt.c             |    1 
 drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h           |    4 
 drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h            |    5 
 drivers/gpu/drm/amd/powerplay/inc/smu_v12_0.h            |    5 
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c               |    1 
 drivers/gpu/drm/amd/powerplay/renoir_ppt.c               |    1 
 drivers/gpu/drm/amd/powerplay/smu_internal.h             |    4 
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c                |   29 -
 drivers/gpu/drm/amd/powerplay/smu_v12_0.c                |   28 
 drivers/gpu/drm/amd/powerplay/vega20_ppt.c               |    1 
 drivers/gpu/drm/drm_dp_mst_topology.c                    |    6 
 drivers/gpu/drm/i915/Kconfig.profile                     |    2 
 drivers/gpu/drm/i915/display/intel_cdclk.c               |    4 
 drivers/gpu/drm/i915/display/intel_ddi.c                 |   29 -
 drivers/gpu/drm/i915/display/intel_dp.c                  |   12 
 drivers/gpu/drm/i915/gem/i915_gem_context.c              |    4 
 drivers/gpu/drm/i915/gt/intel_context.c                  |   21 
 drivers/gpu/drm/i915/gt/intel_engine.h                   |    4 
 drivers/gpu/drm/i915/gt/intel_engine_cs.c                |    8 
 drivers/gpu/drm/i915/gt/intel_engine_pm.c                |   67 ++
 drivers/gpu/drm/i915/gt/intel_engine_pm.h                |   10 
 drivers/gpu/drm/i915/gt/intel_engine_types.h             |    8 
 drivers/gpu/drm/i915/gt/intel_gt_pm.c                    |    3 
 drivers/gpu/drm/i915/gt/intel_gt_pm.h                    |    5 
 drivers/gpu/drm/i915/gt/intel_gt_requests.c              |   83 ++
 drivers/gpu/drm/i915/gt/intel_gt_requests.h              |    7 
 drivers/gpu/drm/i915/gt/intel_lrc.c                      |   50 +
 drivers/gpu/drm/i915/gt/intel_reset.c                    |    2 
 drivers/gpu/drm/i915/gt/intel_ring.c                     |   13 
 drivers/gpu/drm/i915/gt/intel_timeline.c                 |   35 -
 drivers/gpu/drm/i915/gt/intel_timeline_types.h           |    5 
 drivers/gpu/drm/i915/gt/selftest_engine_pm.c             |    7 
 drivers/gpu/drm/i915/gvt/cmd_parser.c                    |    6 
 drivers/gpu/drm/i915/gvt/handlers.c                      |    5 
 drivers/gpu/drm/i915/i915_active.c                       |    5 
 drivers/gpu/drm/i915/i915_pmu.c                          |    6 
 drivers/gpu/drm/i915/i915_query.c                        |    7 
 drivers/gpu/drm/i915/intel_wakeref.c                     |   21 
 drivers/gpu/drm/i915/intel_wakeref.h                     |   45 +
 drivers/gpu/drm/mgag200/mgag200_drv.c                    |   36 +
 drivers/gpu/drm/mgag200/mgag200_drv.h                    |   18 
 drivers/gpu/drm/mgag200/mgag200_main.c                   |    3 
 drivers/gpu/drm/msm/Kconfig                              |    1 
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c                    |   28 
 drivers/gpu/drm/msm/adreno/a3xx_gpu.h                    |    3 
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c                    |   25 
 drivers/gpu/drm/msm/adreno/a4xx_gpu.h                    |    3 
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c                    |   79 ++
 drivers/gpu/drm/msm/adreno/a5xx_power.c                  |    7 
 drivers/gpu/drm/msm/adreno/adreno_device.c               |   15 
 drivers/gpu/drm/msm/adreno/adreno_gpu.c                  |   40 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h                  |   15 
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c             |   43 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c            |   21 
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c                 |   20 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c              |   39 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c     |   15 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c     |    7 
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c                  |   60 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h                  |    4 
 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c                 |    6 
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c                 |   10 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c                 |  114 +++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c                |    3 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c                 |   23 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h                 |    2 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c                 |    2 
 drivers/gpu/drm/msm/dsi/dsi_cfg.c                        |   28 
 drivers/gpu/drm/msm/dsi/dsi_cfg.h                        |    1 
 drivers/gpu/drm/msm/dsi/dsi_host.c                       |    3 
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c                    |    8 
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.h                    |    1 
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c               |   60 +-
 drivers/gpu/drm/msm/hdmi/hdmi_phy.c                      |    8 
 drivers/gpu/drm/msm/msm_gpu.c                            |    6 
 drivers/gpu/drm/msm/msm_gpummu.c                         |    6 
 drivers/gpu/drm/msm/msm_iommu.c                          |    6 
 drivers/gpu/drm/msm/msm_mmu.h                            |    4 
 drivers/gpu/drm/msm/msm_rd.c                             |   16 
 drivers/gpu/drm/omapdrm/omap_gem.c                       |    4 
 drivers/gpu/drm/radeon/r100.c                            |    4 
 drivers/gpu/drm/radeon/r200.c                            |    4 
 drivers/gpu/drm/tegra/dc.c                               |   18 
 drivers/gpu/drm/tegra/drm.c                              |    7 
 drivers/gpu/drm/tegra/gem.c                              |   50 +
 drivers/gpu/drm/tegra/hub.c                              |    3 
 drivers/gpu/drm/tegra/plane.c                            |   11 
 drivers/gpu/drm/tegra/sor.c                              |   38 +
 drivers/gpu/drm/tegra/vic.c                              |    7 
 drivers/soc/qcom/Kconfig                                 |   10 
 drivers/soc/qcom/Makefile                                |    1 
 drivers/soc/qcom/ocmem.c                                 |  433 +++++++++++++++
 include/linux/agpgart.h                                  |    2 
 include/linux/miscdevice.h                               |    1 
 include/linux/qcom_scm.h                                 |   26 
 include/soc/qcom/ocmem.h                                 |   65 ++
 126 files changed, 2014 insertions(+), 764 deletions(-)

New commits:
commit 6ff6d67c69884c9486166acf863fc662253d3ad6
Merge: 4e64a0b97456 9c1867d730a6
Author: Kevin Brace <kevinbrace at gmx.com>
Date:   Wed Dec 11 15:59:00 2019 -0600

    Merge tag 'drm-next-2019-12-06' of git://anongit.freedesktop.org/drm/drm into drm-next-5.5
    
    drm msm + fixes for 5.5-rc1
    
    msm-next:
    - OCMEM support for a3xx and a4xx GPUs.
    - a510 support + display support
    
    core:
    - mst payload deletion fix
    
    i915:
    - uapi alignment fix
    - fix for power usage regression due to security fixes
    - change default preemption timeout to 640ms from 100ms
    - EHL voltage level display fixes
    - TGL DGL PHY fix
    - gvt - MI_ATOMIC cmd parser fix, CFL non-priv warning
    - CI spotted deadlock fix
    - EHL port D programming fix
    
    amdgpu:
    - VRAM lost fixes on BACO for CI/VI
    - navi14 DC fixes
    - misc SR-IOV, gfx10 fixes
    - XGMI fixes for arcturus
    - SRIOV fixes
    
    amdkfd:
    - KFD on ppc64le enabled
    - page table optimisations
    
    radeon:
    - fix for r1xx/2xx register checker.
    
    tegra:
    - displayport regression fixes
    - DMA API regression fixes
    
    mgag200:
    - fix devices that can't scanout except at 0 addr
    
    omap:
    - fix dma_addr refcounting

commit 9c1867d730a6e1dc23dd633392d102860578c047
Merge: b53bd16fec3d 01bb63031933
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Dec 6 13:10:51 2019 +1000

    Merge tag 'drm-intel-next-fixes-2019-12-05' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
    
    - Includes gvt-next-fixes-2019-12-02 pull
    - Fixes for CI spotted eadlock and a race condition in GEM contexts
    - Fix for EHL port D programming
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191205092412.GA8089@jlahtine-desk.ger.corp.intel.com

commit b53bd16fec3d52ff7be1648a9b0a747288f52cf8
Merge: b7fa0cde29c8 e5a6ca27eb72
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Dec 5 11:11:06 2019 +1000

    Merge tag 'drm-misc-next-fixes-2019-12-04' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
    
    mgag200- Fix hw with broken 'startadd' support (Thomas)
    mst- Avoid skipping payloads in payload deletion loop (Wayne)
    omap- Fix dma_addr refcounting (Tomi)
    
    Cc: Wayne Lin <Wayne.Lin at amd.com>
    Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
    Cc: Thomas Zimmermann <tzimmermann at suse.de>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    
    From: Sean Paul <sean at poorly.run>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191204212255.GA256395@art_vandelay

commit b7fa0cde29c87a6d3f0a11d24c46f52549e5a5c1
Merge: 4673402ebf9f d66dfcf80d0f
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Dec 5 10:52:58 2019 +1000

    Merge tag 'drm/tegra/for-5.5-rc1-fixes' of git://anongit.freedesktop.org/tegra/linux into drm-next
    
    drm/tegra: Fixes for v5.5-rc1
    
    This is a set of small fixes, mostly for regressions introduced with the
    DMA API and DisplayPort support in the main pull request for v5.5-rc1.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    
    From: Thierry Reding <thierry.reding at gmail.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191204124316.3534855-1-thierry.reding@gmail.com

commit e5a6ca27eb72c67533ddfc11c06df84beaa167fa
Author: Wayne Lin <Wayne.Lin at amd.com>
Date:   Tue Dec 3 12:24:23 2019 +0800

    drm/dp_mst: Correct the bug in drm_dp_update_payload_part1()
    
    [Why]
    If the payload_state is DP_PAYLOAD_DELETE_LOCAL in series, current
    code doesn't delete the payload at current index and just move the
    index to next one after shuffling payloads.
    
    [How]
    Drop the i++ increasing part in for loop head and decide whether
    to increase the index or not according to payload_state of current
    payload.
    
    Changes since v1:
    * Refine the code to have it easy reading
    * Amend the commit message to meet the way code is modified now.
    
    Signed-off-by: Wayne Lin <Wayne.Lin at amd.com>
    Reviewed-by: Lyude Paul <lyude at redhat.com>
    Fixes: 706246c761dd ("drm/dp_mst: Refactor drm_dp_update_payload_part1()")
    Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
    Cc: Juston Li <juston.li at intel.com>
    Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Cc: Maxime Ripard <mripard at kernel.org>
    Cc: Sean Paul <sean at poorly.run>
    Cc: David Airlie <airlied at linux.ie>
    Cc: Daniel Vetter <daniel at ffwll.ch>
    Cc: dri-devel at lists.freedesktop.org
    Cc: <stable at vger.kernel.org> # v5.1+
    [Added cc for stable]
    Signed-off-by: Lyude Paul <lyude at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191203042423.5961-1-Wayne.Lin@amd.com

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ae5809a1f19a..273dd80fabf3 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3176,9 +3176,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
 			drm_dp_mst_topology_put_port(port);
 	}
 
-	for (i = 0; i < mgr->max_payloads; i++) {
-		if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL)
+	for (i = 0; i < mgr->max_payloads; /* do nothing */) {
+		if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) {
+			i++;
 			continue;
+		}
 
 		DRM_DEBUG_KMS("removing payload %d\n", i);
 		for (j = i; j < mgr->max_payloads - 1; j++) {
commit d9c148cfaf0a99296ad7c92fb8b65952196053ec
Author: Tomi Valkeinen <tomi.valkeinen at ti.com>
Date:   Thu Nov 14 10:03:43 2019 +0200

    drm/omap: fix dma_addr refcounting
    
    cec4fa7511ef7a73eb635834e9d85b25a5b47a98 ("drm/omap: use refcount API to
    track the number of users of dma_addr") changed omap_gem.c to use
    refcounting API to track dma_addr uses.  However, the driver only tracks
    the refcounts for non-contiguous buffers, and the patch didn't fully
    take this in account.
    
    After the patch, the driver always decreased refcount in omap_gem_unpin,
    instead of decreasing the refcount only for non-contiguous buffers. This
    leads to refcounting mismatch.
    
    As for the contiguous cases the refcount is never increased, fix this
    issue by returning from omap_gem_unpin if the buffer being unpinned is
    contiguous.
    
    Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191114080343.30704-1-tomi.valkeinen@ti.com
    Fixes: cec4fa7511ef ("drm/omap: use refcount API to track the number of users of dma_addr")
    Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index e518d93ca6df..d08ae95ecc0a 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -843,9 +843,13 @@ fail:
  */
 static void omap_gem_unpin_locked(struct drm_gem_object *obj)
 {
+	struct omap_drm_private *priv = obj->dev->dev_private;
 	struct omap_gem_object *omap_obj = to_omap_bo(obj);
 	int ret;
 
+	if (omap_gem_is_contiguous(omap_obj) || !priv->has_dmm)
+		return;
+
 	if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) {
 		ret = tiler_unpin(omap_obj->block);
 		if (ret) {
commit d66dfcf80d0f55f95b9ea4a45ca41cc7115e9789
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:14 2019 +0100

    drm/tegra: Run hub cleanup on ->remove()
    
    The call to tegra_display_hub_cleanup() that takes care of disabling the
    window groups is missing from the driver's ->remove() callback. Call it
    to make sure the runtime PM reference counts for the display controllers
    are balanced.
    
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 7a16b51eaa2d..f455ce71e85d 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1241,6 +1241,9 @@ static int host1x_drm_remove(struct host1x_device *dev)
 	drm_atomic_helper_shutdown(drm);
 	drm_mode_config_cleanup(drm);
 
+	if (tegra->hub)
+		tegra_display_hub_cleanup(tegra->hub);
+
 	err = host1x_device_exit(dev);
 	if (err < 0)
 		dev_err(&dev->dev, "host1x device cleanup failed: %d\n", err);
commit b06e145f7030bea2f307d3dc68a6b9aaf2dd905c
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:13 2019 +0100

    drm/tegra: sor: Make the +5V HDMI supply optional
    
    The SOR supports multiple display modes, but only when driving an HDMI
    monitor does it make sense to control the +5V power supply. eDP and DP
    don't need this, so make it optional.
    
    This fixes a crash observed during system suspend/resume.
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 2200f4cd397a..a68d3b36b972 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -3970,15 +3970,29 @@ static int tegra_sor_runtime_resume(struct device *dev)
 static int tegra_sor_suspend(struct device *dev)
 {
 	struct tegra_sor *sor = dev_get_drvdata(dev);
+	int err;
+
+	if (sor->hdmi_supply) {
+		err = regulator_disable(sor->hdmi_supply);
+		if (err < 0)
+			return err;
+	}
 
-	return regulator_disable(sor->hdmi_supply);
+	return 0;
 }
 
 static int tegra_sor_resume(struct device *dev)
 {
 	struct tegra_sor *sor = dev_get_drvdata(dev);
+	int err;
+
+	if (sor->hdmi_supply) {
+		err = regulator_enable(sor->hdmi_supply);
+		if (err < 0)
+			return err;
+	}
 
-	return regulator_enable(sor->hdmi_supply);
+	return 0;
 }
 
 static const struct dev_pm_ops tegra_sor_pm_ops = {
commit a8817489dc3e3b1910842958a3b9d9e4832e99b0
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:12 2019 +0100

    drm/tegra: Silence expected errors on IOMMU attach
    
    Subdevices may not be hooked up to an IOMMU via device tree. Detect such
    situations and avoid confusing users by not emitting an error message.
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 85d3c9ad29df..714af052fbef 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -2017,7 +2017,7 @@ static int tegra_dc_init(struct host1x_client *client)
 		dev_warn(dc->dev, "failed to allocate syncpoint\n");
 
 	err = host1x_client_iommu_attach(client);
-	if (err < 0) {
+	if (err < 0 && err != -ENODEV) {
 		dev_err(client->dev, "failed to attach to domain: %d\n", err);
 		return err;
 	}
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 56e5e7a5c108..7a16b51eaa2d 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -920,10 +920,8 @@ int host1x_client_iommu_attach(struct host1x_client *client)
 
 	if (tegra->domain) {
 		group = iommu_group_get(client->dev);
-		if (!group) {
-			dev_err(client->dev, "failed to get IOMMU group\n");
+		if (!group)
 			return -ENODEV;
-		}
 
 		if (domain != tegra->domain) {
 			err = iommu_attach_group(tegra->domain, group);
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index c4d82b8b3065..3526c2892ddb 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -167,7 +167,7 @@ static int vic_init(struct host1x_client *client)
 	int err;
 
 	err = host1x_client_iommu_attach(client);
-	if (err < 0) {
+	if (err < 0 && err != -ENODEV) {
 		dev_err(vic->dev, "failed to attach to domain: %d\n", err);
 		return err;
 	}
commit 82d73874d422b43359698f73c418a02322c886d5
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:11 2019 +0100

    drm/tegra: vic: Export module device table
    
    Export the module device table to ensure the VIC compatible strings are
    listed in the module's aliases table. This in turn causes the driver to
    be automatically loaded on boot if VIC is the only enabled subdevice of
    the logical host1x DRM device.
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index 9444ba183990..c4d82b8b3065 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -386,13 +386,14 @@ static const struct vic_config vic_t194_config = {
 	.supports_sid = true,
 };
 
-static const struct of_device_id vic_match[] = {
+static const struct of_device_id tegra_vic_of_match[] = {
 	{ .compatible = "nvidia,tegra124-vic", .data = &vic_t124_config },
 	{ .compatible = "nvidia,tegra210-vic", .data = &vic_t210_config },
 	{ .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config },
 	{ .compatible = "nvidia,tegra194-vic", .data = &vic_t194_config },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_vic_of_match);
 
 static int vic_probe(struct platform_device *pdev)
 {
@@ -516,7 +517,7 @@ static const struct dev_pm_ops vic_pm_ops = {
 struct platform_driver tegra_vic_driver = {
 	.driver = {
 		.name = "tegra-vic",
-		.of_match_table = vic_match,
+		.of_match_table = tegra_vic_of_match,
 		.pm = &vic_pm_ops
 	},
 	.probe = vic_probe,
commit be0b23f28c028bf11e47d16f79c784106286bcb7
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:10 2019 +0100

    drm/tegra: sor: Implement system suspend/resume
    
    Upon system suspend, make sure the +5V HDMI regulator is disabled. This
    avoids potentially leaking current to the HDMI connector. This also
    makes sure that upon resume the regulator is enabled again, which in
    some cases is necessary to properly restore the state of the supply on
    resume.
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 615cb319fa8b..2200f4cd397a 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -3912,8 +3912,7 @@ static int tegra_sor_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int tegra_sor_suspend(struct device *dev)
+static int tegra_sor_runtime_suspend(struct device *dev)
 {
 	struct tegra_sor *sor = dev_get_drvdata(dev);
 	int err;
@@ -3935,7 +3934,7 @@ static int tegra_sor_suspend(struct device *dev)
 	return 0;
 }
 
-static int tegra_sor_resume(struct device *dev)
+static int tegra_sor_runtime_resume(struct device *dev)
 {
 	struct tegra_sor *sor = dev_get_drvdata(dev);
 	int err;
@@ -3967,10 +3966,25 @@ static int tegra_sor_resume(struct device *dev)
 
 	return 0;
 }
-#endif
+
+static int tegra_sor_suspend(struct device *dev)
+{
+	struct tegra_sor *sor = dev_get_drvdata(dev);
+
+	return regulator_disable(sor->hdmi_supply);
+}
+
+static int tegra_sor_resume(struct device *dev)
+{
+	struct tegra_sor *sor = dev_get_drvdata(dev);
+
+	return regulator_enable(sor->hdmi_supply);
+}
 
 static const struct dev_pm_ops tegra_sor_pm_ops = {
-	SET_RUNTIME_PM_OPS(tegra_sor_suspend, tegra_sor_resume, NULL)
+	SET_RUNTIME_PM_OPS(tegra_sor_runtime_suspend, tegra_sor_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)
 };
 
 struct platform_driver tegra_sor_driver = {
commit c52e167b41940186d0f4d7364950b654b79b3ef7
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:09 2019 +0100

    drm/tegra: Use proper IOVA address for cursor image
    
    The IOVA address for the cursor is the result of mapping the buffer
    object for the given display controller. Make sure to use the proper
    IOVA address as stored in the cursor's plane state.
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 5b1f9ff97576..85d3c9ad29df 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -837,16 +837,15 @@ static int tegra_cursor_atomic_check(struct drm_plane *plane,
 static void tegra_cursor_atomic_update(struct drm_plane *plane,
 				       struct drm_plane_state *old_state)
 {
-	struct tegra_bo *bo = tegra_fb_get_plane(plane->state->fb, 0);
+	struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
 	struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
-	struct drm_plane_state *state = plane->state;
 	u32 value = CURSOR_CLIP_DISPLAY;
 
 	/* rien ne va plus */
 	if (!plane->state->crtc || !plane->state->fb)
 		return;
 
-	switch (state->crtc_w) {
+	switch (plane->state->crtc_w) {
 	case 32:
 		value |= CURSOR_SIZE_32x32;
 		break;
@@ -864,16 +863,16 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
 		break;
 
 	default:
-		WARN(1, "cursor size %ux%u not supported\n", state->crtc_w,
-		     state->crtc_h);
+		WARN(1, "cursor size %ux%u not supported\n",
+		     plane->state->crtc_w, plane->state->crtc_h);
 		return;
 	}
 
-	value |= (bo->iova >> 10) & 0x3fffff;
+	value |= (state->iova[0] >> 10) & 0x3fffff;
 	tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR);
 
 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-	value = (bo->iova >> 32) & 0x3;
+	value = (state->iova[0] >> 32) & 0x3;
 	tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI);
 #endif
 
@@ -892,7 +891,8 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
 	tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);
 
 	/* position the cursor */
-	value = (state->crtc_y & 0x3fff) << 16 | (state->crtc_x & 0x3fff);
+	value = (plane->state->crtc_y & 0x3fff) << 16 |
+		(plane->state->crtc_x & 0x3fff);
 	tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
 }
 
commit 49f821919bb9d45de7f1cde6072de01d36235b5d
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:08 2019 +0100

    drm/tegra: gem: Remove premature import restrictions
    
    All the display related blocks on Tegra require contiguous memory. Using
    the DMA API, there is no knowing at import time which device will end up
    using the buffer, so it's not known whether or not an IOMMU will be used
    to map the buffer.
    
    Move the check for non-contiguous buffers/mappings to the tegra_dc_pin()
    function which is now the earliest point where it is known if a DMA BUF
    can be used by the given device or not.
    
    v2: add check for contiguous buffer/mapping in tegra_dc_pin()
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6dfad56eee2b..bc15b430156d 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -440,13 +440,6 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
 		err = tegra_bo_iommu_map(tegra, bo);
 		if (err < 0)
 			goto detach;
-	} else {
-		if (bo->sgt->nents > 1) {
-			err = -EINVAL;
-			goto detach;
-		}
-
-		bo->iova = sg_dma_address(bo->sgt->sgl);
 	}
 
 	bo->gem.import_attach = attach;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 163b590be224..cadcdd9ea427 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -129,6 +129,17 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 				goto unpin;
 			}
 
+			/*
+			 * The display controller needs contiguous memory, so
+			 * fail if the buffer is discontiguous and we fail to
+			 * map its SG table to a single contiguous chunk of
+			 * I/O virtual memory.
+			 */
+			if (err > 1) {
+				err = -EINVAL;
+				goto unpin;
+			}
+
 			state->iova[i] = sg_dma_address(sgt->sgl);
 			state->sgt[i] = sgt;
 		} else {
commit 1f16deac766926f1f59a7c038e939b09ef8edfc8
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:07 2019 +0100

    drm/tegra: gem: Properly pin imported buffers
    
    Buffers that are imported from a DMA-BUF don't have pages allocated with
    them. At the same time an SG table for them can't be derived using the
    DMA API helpers because the necessary information doesn't exist. However
    there's already an SG table that was created during import, so this can
    simply be duplicated.
    
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 746dae32c484..6dfad56eee2b 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -27,6 +27,29 @@ static void tegra_bo_put(struct host1x_bo *bo)
 	drm_gem_object_put_unlocked(&obj->gem);
 }
 
+/* XXX move this into lib/scatterlist.c? */
+static int sg_alloc_table_from_sg(struct sg_table *sgt, struct scatterlist *sg,
+				  unsigned int nents, gfp_t gfp_mask)
+{
+	struct scatterlist *dst;
+	unsigned int i;
+	int err;
+
+	err = sg_alloc_table(sgt, nents, gfp_mask);
+	if (err < 0)
+		return err;
+
+	dst = sgt->sgl;
+
+	for (i = 0; i < nents; i++) {
+		sg_set_page(dst, sg_page(sg), sg->length, 0);
+		dst = sg_next(dst);
+		sg = sg_next(sg);
+	}
+
+	return 0;
+}
+
 static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 				     dma_addr_t *phys)
 {
@@ -52,11 +75,31 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		return ERR_PTR(-ENOMEM);
 
 	if (obj->pages) {
+		/*
+		 * If the buffer object was allocated from the explicit IOMMU
+		 * API code paths, construct an SG table from the pages.
+		 */
 		err = sg_alloc_table_from_pages(sgt, obj->pages, obj->num_pages,
 						0, obj->gem.size, GFP_KERNEL);
 		if (err < 0)
 			goto free;
+	} else if (obj->sgt) {
+		/*
+		 * If the buffer object already has an SG table but no pages
+		 * were allocated for it, it means the buffer was imported and
+		 * the SG table needs to be copied to avoid overwriting any
+		 * other potential users of the original SG table.
+		 */
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
+					     GFP_KERNEL);
+		if (err < 0)
+			goto free;
 	} else {
+		/*
+		 * If the buffer object had no pages allocated and if it was
+		 * not imported, it had to be allocated with the DMA API, so
+		 * the DMA API helper can be used.
+		 */
 		err = dma_get_sgtable(dev, sgt, obj->vaddr, obj->iova,
 				      obj->gem.size);
 		if (err < 0)
commit 9569c3e9227c03e2b5eb341676e46b0bcbbeaa01
Author: Thierry Reding <treding at nvidia.com>
Date:   Tue Dec 3 17:19:06 2019 +0100

    drm/tegra: hub: Remove bogus connection mutex check
    
    The Tegra DRM never actually took that lock, so the driver was broken
    until generic locking was added in commit:
    
            commit b962a12050a387e4bbf3a48745afe1d29d396b0d
            Author: Rob Clark <robdclark at gmail.com>
            Date:   Mon Oct 22 14:31:22 2018 +0200
    
                drm/atomic: integrate modeset lock with private objects
    
    It's now no longer necessary to take that lock, so drop the check.
    
    v2: add rationale for why it is now safe to drop the check (Daniel)
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Thierry Reding <treding at nvidia.com>

diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index 2b4082d0bc9e..47d985ac7cd7 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -605,11 +605,8 @@ static struct tegra_display_hub_state *
 tegra_display_hub_get_state(struct tegra_display_hub *hub,
 			    struct drm_atomic_state *state)
 {
-	struct drm_device *drm = dev_get_drvdata(hub->client.parent);
 	struct drm_private_state *priv;
 
-	WARN_ON(!drm_modeset_is_locked(&drm->mode_config.connection_mutex));
-
 	priv = drm_atomic_get_private_obj_state(state, &hub->base);
 	if (IS_ERR(priv))
 		return ERR_CAST(priv);
commit 4673402ebf9fc1712fb41cce6a808923481495f3
Author: Corentin Labbe <clabbe at baylibre.com>
Date:   Thu Nov 21 08:14:45 2019 +0000

    ia64: agp: Replace empty define with do while
    
    It's dangerous to use empty code define.
    Furthermore it lead to the following warning:
    drivers/char/agp/generic.c: In function « agp_generic_destroy_page »:
    drivers/char/agp/generic.c:1266:28: attention : suggest braces around empty body in an « if » statement [-Wempty-body]
    
    So let's replace emptyness by "do {} while(0)"
    
    Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
    Acked-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/1574324085-4338-6-git-send-email-clabbe@baylibre.com

diff --git a/arch/ia64/include/asm/agp.h b/arch/ia64/include/asm/agp.h
index 2b451c4496da..0261507dc264 100644
--- a/arch/ia64/include/asm/agp.h
+++ b/arch/ia64/include/asm/agp.h
@@ -14,8 +14,8 @@
  * in coherent mode, which lets us map the AGP memory as normal (write-back) memory
  * (unlike x86, where it gets mapped "write-coalescing").
  */
-#define map_page_into_agp(page)		/* nothing */
-#define unmap_page_from_agp(page)	/* nothing */
+#define map_page_into_agp(page)		do { } while (0)
+#define unmap_page_from_agp(page)	do { } while (0)
 #define flush_agp_cache()		mb()
 
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
commit 5f448266ce9632c5318a5dbbc024fc7951f089d7
Author: Corentin Labbe <clabbe at baylibre.com>
Date:   Thu Nov 21 08:14:44 2019 +0000

    agp: Add bridge parameter documentation
    
    This patch add documentation about the bridge parameter in several
    function.
    
    This will fix the following build warning:
    drivers/char/agp/generic.c:220: warning: No description found for parameter 'bridge'
    drivers/char/agp/generic.c:364: warning: No description found for parameter 'bridge'
    drivers/char/agp/generic.c:1283: warning: No description found for parameter 'bridge'
    
    Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
    Acked-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/1574324085-4338-5-git-send-email-clabbe@baylibre.com

diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 4d2eb0800b2a..ab154a75acf0 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -207,6 +207,7 @@ EXPORT_SYMBOL(agp_free_memory);
 /**
  *	agp_allocate_memory  -  allocate a group of pages of a certain type.
  *
+ *	@bridge: an agp_bridge_data struct allocated for the AGP host bridge.
  *	@page_count:	size_t argument of the number of pages
  *	@type:	u32 argument of the type of memory to be allocated.
  *
@@ -355,6 +356,7 @@ EXPORT_SYMBOL_GPL(agp_num_entries);
 /**
  *	agp_copy_info  -  copy bridge state information
  *
+ *	@bridge: an agp_bridge_data struct allocated for the AGP host bridge.
  *	@info:		agp_kern_info pointer.  The caller should insure that this pointer is valid.
  *
  *	This function copies information about the agp bridge device and the state of
@@ -1277,6 +1279,7 @@ EXPORT_SYMBOL(agp_generic_destroy_page);
 /**
  * agp_enable  -  initialise the agp point-to-point connection.
  *
+ * @bridge: an agp_bridge_data struct allocated for the AGP host bridge.
  * @mode:	agp mode register value to configure with.
  */
 void agp_enable(struct agp_bridge_data *bridge, u32 mode)
commit 5f1b24a6445ddbfccc8de1f5c1a31394a5b9ac66
Author: Corentin Labbe <clabbe at baylibre.com>
Date:   Thu Nov 21 08:14:43 2019 +0000

    agp: remove unused variable num_segments
    
    This patch fix the following build warning:
    warning: variable 'num_segments' set but not used [-Wunused-but-set-variable]
    
    Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
    Acked-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/1574324085-4338-4-git-send-email-clabbe@baylibre.com

diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index f6955888e676..47098648502d 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -102,14 +102,13 @@ agp_segment_priv *agp_find_seg_in_client(const struct agp_client *client,
 					    int size, pgprot_t page_prot)
 {
 	struct agp_segment_priv *seg;
-	int num_segments, i;
+	int i;
 	off_t pg_start;
 	size_t pg_count;
 
 	pg_start = offset / 4096;
 	pg_count = size / 4096;
 	seg = *(client->segments);
-	num_segments = client->num_segments;
 
 	for (i = 0; i < client->num_segments; i++) {
 		if ((seg[i].pg_start == pg_start) &&
commit 0f109f0e9a608c381846b3f2270a6a7b72158cb4
Author: Corentin Labbe <clabbe at baylibre.com>
Date:   Thu Nov 21 08:14:42 2019 +0000

    agp: move AGPGART_MINOR to include/linux/miscdevice.h
    
    This patch move the define for AGPGART_MINOR to include/linux/miscdevice.h.
    It is better that all minor number definitions are in the same place.
    
    Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
    Acked-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/1574324085-4338-3-git-send-email-clabbe@baylibre.com

diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h
index c6b61ca97053..21b34a96cfd8 100644
--- a/include/linux/agpgart.h
+++ b/include/linux/agpgart.h
@@ -30,8 +30,6 @@
 #include <linux/agp_backend.h>
 #include <uapi/linux/agpgart.h>
 
-#define AGPGART_MINOR 175
-
 struct agp_info {
 	struct agp_version version;	/* version of the driver        */
 	u32 bridge_id;		/* bridge vendor/device         */
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 3247a3dc7934..6f2ca42152a0 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -33,6 +33,7 @@
 #define SGI_MMTIMER		153
 #define STORE_QUEUE_MINOR	155	/* unused */
 #define I2O_MINOR		166
+#define AGPGART_MINOR		175
 #define HWRNG_MINOR		183
 #define MICROCODE_MINOR		184
 #define IRNET_MINOR		187
commit 9fc785f17dec699cfe3891077e7506c92193a91b
Author: Corentin Labbe <clabbe at baylibre.com>
Date:   Thu Nov 21 08:14:41 2019 +0000

    agp: remove unused variable size in agp_generic_create_gatt_table
    
    This patch fix the following warning:
    drivers/char/agp/generic.c:853:6: attention : variable ‘size’ set but not used [-Wunused-but-set-variable]
    by removing the unused variable size in agp_generic_create_gatt_table
    
    Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
    Acked-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/1574324085-4338-2-git-send-email-clabbe@baylibre.com

diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index df1edb5ec0ad..4d2eb0800b2a 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -850,7 +850,6 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 {
 	char *table;
 	char *table_end;
-	int size;
 	int page_order;
 	int num_entries;
 	int i;
@@ -864,25 +863,22 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 	table = NULL;
 	i = bridge->aperture_size_idx;
 	temp = bridge->current_size;
-	size = page_order = num_entries = 0;
+	page_order = num_entries = 0;
 
 	if (bridge->driver->size_type != FIXED_APER_SIZE) {
 		do {
 			switch (bridge->driver->size_type) {
 			case U8_APER_SIZE:
-				size = A_SIZE_8(temp)->size;
 				page_order =
 				    A_SIZE_8(temp)->page_order;
 				num_entries =
 				    A_SIZE_8(temp)->num_entries;
 				break;
 			case U16_APER_SIZE:
-				size = A_SIZE_16(temp)->size;
 				page_order = A_SIZE_16(temp)->page_order;
 				num_entries = A_SIZE_16(temp)->num_entries;
 				break;
 			case U32_APER_SIZE:
-				size = A_SIZE_32(temp)->size;
 				page_order = A_SIZE_32(temp)->page_order;
 				num_entries = A_SIZE_32(temp)->num_entries;
 				break;
@@ -890,7 +886,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 			case FIXED_APER_SIZE:
 			case LVL2_APER_SIZE:
 			default:
-				size = page_order = num_entries = 0;
+				page_order = num_entries = 0;
 				break;
 			}
 
@@ -920,7 +916,6 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 			}
 		} while (!table && (i < bridge->driver->num_aperture_sizes));
 	} else {
-		size = ((struct aper_size_info_fixed *) temp)->size;
 		page_order = ((struct aper_size_info_fixed *) temp)->page_order;
 		num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
 		table = alloc_gatt_pages(page_order);
commit 909a60652624b837aff16825197c6a21d84fec82
Merge: 3e25dbca8b75 008037d4d972
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Dec 4 10:13:16 2019 +1000

    Merge tag 'drm-next-5.5-2019-12-03' of git://people.freedesktop.org/~agd5f/linux into drm-next
    
    drm-next-5.5-2019-12-03:
    
    amdgpu:
    - Fix vram lost handling with BACO on VI/CI asics
    - DC fixes for Navi14
    - Misc gfx10 fixes
    - SR-IOV fixes
    - Fix driver unload
    - Fix XGMI limits on Arcturus
    
    amdkfd:
    - Enable KFD on PPC
    - Optimize KFD page table reservations
    
    radeon:
    - Fix register checker for r1xx/r2xx
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Alex Deucher <alexdeucher at gmail.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191203204135.5437-1-alexander.deucher@amd.com

commit d6d07ca19c045924f2b9cac14cb277cc34f85d43
Author: Guenter Roeck <linux at roeck-us.net>
Date:   Mon Dec 2 05:36:50 2019 -0800

    drm/dp_mst: Fix build on systems with STACKTRACE_SUPPORT=n
    
    On systems with STACKTRACE_SUPPORT=n, we get:
    
    WARNING: unmet direct dependencies detected for STACKTRACE
      Depends on [n]: STACKTRACE_SUPPORT
      Selected by [y]:
      - STACKDEPOT [=y]
    
    and build errors such as:
    
    m68k-linux-ld: kernel/stacktrace.o: in function `stack_trace_save':
    (.text+0x11c): undefined reference to `save_stack_trace'
    
    Add the missing deendency on STACKTRACE_SUPPORT.
    
    Fixes: 12a280c72868 ("drm/dp_mst: Add topology ref history tracking for debugging")
    Cc: Lyude Paul <lyude at redhat.com>
    Cc: Sean Paul <sean at poorly.run>
    Signed-off-by: Guenter Roeck <linux at roeck-us.net>
    Signed-off-by: Lyude Paul <lyude at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191202133650.11964-1-linux@roeck-us.net

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 617d9c3a86c3..58e9772c2586 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KMS_FB_HELPER
 
 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
         bool "Enable refcount backtrace history in the DP MST helpers"
+	depends on STACKTRACE_SUPPORT
         select STACKDEPOT
         depends on DRM_KMS_HELPER
         depends on DEBUG_KERNEL
commit 008037d4d972c9c47b273e40e52ae34f9d9e33e7
Author: Alex Deucher <alexander.deucher at amd.com>
Date:   Tue Nov 26 09:41:46 2019 -0500

    drm/radeon: fix r1xx/r2xx register checker for POT textures
    
    Shift and mask were reversed.  Noticed by chance.
    
    Tested-by: Meelis Roos <mroos at linux.ee>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 7089dfc8c2a9..110fb38004b1 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1826,8 +1826,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
 			track->textures[i].use_pitch = 1;
 		} else {
 			track->textures[i].use_pitch = 0;
-			track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
-			track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+			track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
+			track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
 		}
 		if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
 			track->textures[i].tex_coord_type = 2;
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index 840401413c58..f5f2ffea5ab2 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -476,8 +476,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
 			track->textures[i].use_pitch = 1;
 		} else {
 			track->textures[i].use_pitch = 0;
-			track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
-			track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+			track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
+			track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
 		}
 		if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
 			track->textures[i].lookup_disable = true;
commit 4905880b4515721bc4aff17d65be426175d9ddbf
Author: Monk Liu <Monk.Liu at amd.com>
Date:   Tue Nov 26 19:33:38 2019 +0800

    drm/amdgpu: fix GFX10 missing CSIB set(v3)
    
    still need to init csb even for SRIOV
    
    v2:
    drop init_pg() for gfx10 at all since
    PG and GFX off feature will be fully controled
    by RLC and SMU fw for gfx10
    
    v3:
    drop the flush_gpu_tlb lines since we consider
    it is only usefull in emulation
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 4745796701cb..f2c1b026397b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -1768,22 +1768,6 @@ static int gfx_v10_0_init_csb(struct amdgpu_device *adev)
 	return 0;
 }
 
-static int gfx_v10_0_init_pg(struct amdgpu_device *adev)
-{
-	int i;
-	int r;
-
-	r = gfx_v10_0_init_csb(adev);
-	if (r)
-		return r;
-
-	for (i = 0; i < adev->num_vmhubs; i++)
-		amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
-
-	/* TODO: init power gating */
-	return 0;
-}
-
 void gfx_v10_0_rlc_stop(struct amdgpu_device *adev)
 {
 	u32 tmp = RREG32_SOC15(GC, 0, mmRLC_CNTL);
@@ -1876,21 +1860,16 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev)
 {
 	int r;
 
-	if (amdgpu_sriov_vf(adev))
-		return 0;
-
 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
-		r = gfx_v10_0_wait_for_rlc_autoload_complete(adev);
-		if (r)
-			return r;
 
-		r = gfx_v10_0_init_pg(adev);
+		r = gfx_v10_0_wait_for_rlc_autoload_complete(adev);
 		if (r)
 			return r;
 
-		/* enable RLC SRM */
-		gfx_v10_0_rlc_enable_srm(adev);
+		gfx_v10_0_init_csb(adev);
 
+		if (!amdgpu_sriov_vf(adev)) /* enable RLC SRM */
+			gfx_v10_0_rlc_enable_srm(adev);
 	} else {
 		adev->gfx.rlc.funcs->stop(adev);
 
@@ -1912,9 +1891,7 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev)
 				return r;
 		}
 
-		r = gfx_v10_0_init_pg(adev);
-		if (r)
-			return r;
+		gfx_v10_0_init_csb(adev);
 
 		adev->gfx.rlc.funcs->start(adev);
 
commit cd05b51aaa6ea6f7e4c22802e3f2703ac6087912
Author: Monk Liu <Monk.Liu at amd.com>
Date:   Fri Nov 29 16:20:51 2019 +0800

    drm/amdgpu: should stop GFX ring in hw_fini
    
    To align with the scheme from gfx9
    
    disabling GFX ring after VM shutdown could avoid
    garbage data be fetched to GFX RB which may lead
    to unnecessary screw up on GFX
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index c78cc2b2a4cd..4745796701cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -3809,7 +3809,7 @@ static int gfx_v10_0_hw_fini(void *handle)
 	if (amdgpu_gfx_disable_kcq(adev))
 		DRM_ERROR("KCQ disable failed\n");
 	if (amdgpu_sriov_vf(adev)) {
-		pr_debug("For SRIOV client, shouldn't do anything.\n");
+		gfx_v10_0_cp_gfx_enable(adev, false);
 		return 0;
 	}
 	gfx_v10_0_cp_enable(adev, false);
commit dacf56e45ded829a87cefab17bf6800d6cacd236
Author: Monk Liu <Monk.Liu at amd.com>
Date:   Tue Nov 26 19:38:22 2019 +0800

    drm/amdgpu: do autoload right after MEC loaded for SRIOV VF
    
    since we don't have RLCG ucode loading and no SRlist as well
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 2770cba56a6b..44be3a45b25e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -1487,8 +1487,8 @@ out:
 			return ret;
 
 		/* Start rlc autoload after psp recieved all the gfx firmware */
-		if (psp->autoload_supported && ucode->ucode_id ==
-			AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) {
+		if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
+		    AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) {
 			ret = psp_rlc_autoload(psp);
 			if (ret) {
 				DRM_ERROR("Failed to start rlc autoload\n");
commit 6294017fe3525bb45c259db97ab4ac0620af5107
Author: Monk Liu <Monk.Liu at amd.com>
Date:   Tue Nov 26 19:36:29 2019 +0800

    drm/amdgpu: skip rlc ucode loading for SRIOV gfx10
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index ebc13e76edb7..c78cc2b2a4cd 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -690,59 +690,61 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
 	adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
 	adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
 
-	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
-	err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
-	if (err)
-		goto out;
-	err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
-	rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
-	version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
-	version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
-	if (version_major == 2 && version_minor == 1)
-		adev->gfx.rlc.is_rlc_v2_1 = true;
-
-	adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
-	adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
-	adev->gfx.rlc.save_and_restore_offset =
+	if (!amdgpu_sriov_vf(adev)) {
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
+		err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
+		if (err)
+			goto out;
+		err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
+		rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
+		version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
+		version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
+		if (version_major == 2 && version_minor == 1)
+			adev->gfx.rlc.is_rlc_v2_1 = true;
+
+		adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
+		adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
+		adev->gfx.rlc.save_and_restore_offset =
 			le32_to_cpu(rlc_hdr->save_and_restore_offset);
-	adev->gfx.rlc.clear_state_descriptor_offset =
+		adev->gfx.rlc.clear_state_descriptor_offset =
 			le32_to_cpu(rlc_hdr->clear_state_descriptor_offset);
-	adev->gfx.rlc.avail_scratch_ram_locations =
+		adev->gfx.rlc.avail_scratch_ram_locations =
 			le32_to_cpu(rlc_hdr->avail_scratch_ram_locations);
-	adev->gfx.rlc.reg_restore_list_size =
+		adev->gfx.rlc.reg_restore_list_size =
 			le32_to_cpu(rlc_hdr->reg_restore_list_size);
-	adev->gfx.rlc.reg_list_format_start =
+		adev->gfx.rlc.reg_list_format_start =
 			le32_to_cpu(rlc_hdr->reg_list_format_start);
-	adev->gfx.rlc.reg_list_format_separate_start =
+		adev->gfx.rlc.reg_list_format_separate_start =
 			le32_to_cpu(rlc_hdr->reg_list_format_separate_start);
-	adev->gfx.rlc.starting_offsets_start =
+		adev->gfx.rlc.starting_offsets_start =
 			le32_to_cpu(rlc_hdr->starting_offsets_start);
-	adev->gfx.rlc.reg_list_format_size_bytes =
+		adev->gfx.rlc.reg_list_format_size_bytes =
 			le32_to_cpu(rlc_hdr->reg_list_format_size_bytes);
-	adev->gfx.rlc.reg_list_size_bytes =
+		adev->gfx.rlc.reg_list_size_bytes =
 			le32_to_cpu(rlc_hdr->reg_list_size_bytes);
-	adev->gfx.rlc.register_list_format =
+		adev->gfx.rlc.register_list_format =
 			kmalloc(adev->gfx.rlc.reg_list_format_size_bytes +
-				adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
-	if (!adev->gfx.rlc.register_list_format) {
-		err = -ENOMEM;
-		goto out;
-	}
+					adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
+		if (!adev->gfx.rlc.register_list_format) {
+			err = -ENOMEM;
+			goto out;
+		}
 
-	tmp = (unsigned int *)((uintptr_t)rlc_hdr +
-			le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
-	for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
-		adev->gfx.rlc.register_list_format[i] =	le32_to_cpu(tmp[i]);
+		tmp = (unsigned int *)((uintptr_t)rlc_hdr +
+							   le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
+		for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
+			adev->gfx.rlc.register_list_format[i] =	le32_to_cpu(tmp[i]);
 
-	adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
+		adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
 
-	tmp = (unsigned int *)((uintptr_t)rlc_hdr +
-			le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
-	for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
-		adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
+		tmp = (unsigned int *)((uintptr_t)rlc_hdr +
+							   le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
+		for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
+			adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
 
-	if (adev->gfx.rlc.is_rlc_v2_1)
-		gfx_v10_0_init_rlc_ext_microcode(adev);
+		if (adev->gfx.rlc.is_rlc_v2_1)
+			gfx_v10_0_init_rlc_ext_microcode(adev);
+	}
 
 	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks);
 	err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
commit 747d4f715fb5aca0002216355df28714cc20250c
Author: Monk Liu <Monk.Liu at amd.com>
Date:   Tue Nov 26 19:42:25 2019 +0800

    drm/amdgpu: fix calltrace during kmd unload(v3)
    
    issue:
    kernel would report a warning from a double unpin
    during the driver unloading on the CSB bo
    
    why:
    we unpin it during hw_fini, and there will be another
    unpin in sw_fini on CSB bo.
    
    fix:
    actually we don't need to pin/unpin it during
    hw_init/fini since it is created with kernel pinned,
    we only need to fullfill the CSB again during hw_init
    to prevent CSB/VRAM lost after S3
    
    v2:
    get_csb in init_rlc so hw_init() will make CSIB content
    back even after reset or s3
    
    v3:
    use bo_create_kernel instead of bo_create_reserved for CSB
    otherwise the bo_free_kernel() on CSB is not aligned and
    would lead to its internal reserve pending there forever
    
    take care of gfx7/8 as well
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Reviewed-by: Xiaojie Yuan <xiaojie.yuan at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
index c8793e6cc3c5..6373bfb47d55 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
@@ -124,13 +124,12 @@ int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws)
  */
 int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
 {
-	volatile u32 *dst_ptr;
 	u32 dws;
 	int r;
 
 	/* allocate clear state block */
 	adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev);
-	r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+	r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
 				      AMDGPU_GEM_DOMAIN_VRAM,
 				      &adev->gfx.rlc.clear_state_obj,
 				      &adev->gfx.rlc.clear_state_gpu_addr,
@@ -141,13 +140,6 @@ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
 		return r;
 	}
 
-	/* set up the cs buffer */
-	dst_ptr = adev->gfx.rlc.cs_ptr;
-	adev->gfx.rlc.funcs->get_csb_buffer(adev, dst_ptr);
-	amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
-	amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 208fb9cd1482..ebc13e76edb7 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -993,39 +993,6 @@ static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
 	return 0;
 }
 
-static int gfx_v10_0_csb_vram_pin(struct amdgpu_device *adev)
-{
-	int r;
-
-	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-	if (unlikely(r != 0))
-		return r;
-
-	r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
-			AMDGPU_GEM_DOMAIN_VRAM);
-	if (!r)
-		adev->gfx.rlc.clear_state_gpu_addr =
-			amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
-
-	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
-	return r;
-}
-
-static void gfx_v10_0_csb_vram_unpin(struct amdgpu_device *adev)
-{
-	int r;
-
-	if (!adev->gfx.rlc.clear_state_obj)
-		return;
-
-	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
-	if (likely(r == 0)) {
-		amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-	}
-}
-
 static void gfx_v10_0_mec_fini(struct amdgpu_device *adev)
 {
 	amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -1787,25 +1754,7 @@ static void gfx_v10_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
 
 static int gfx_v10_0_init_csb(struct amdgpu_device *adev)
 {
-	int r;
-
-	if (adev->in_gpu_reset) {
-		r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-		if (r)
-			return r;
-
-		r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj,
-				   (void **)&adev->gfx.rlc.cs_ptr);
-		if (!r) {
-			adev->gfx.rlc.funcs->get_csb_buffer(adev,
-					adev->gfx.rlc.cs_ptr);
-			amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
-		}
-
-		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-		if (r)
-			return r;
-	}
+	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
 
 	/* csib */
 	WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI,
@@ -3776,10 +3725,6 @@ static int gfx_v10_0_hw_init(void *handle)
 	int r;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-	r = gfx_v10_0_csb_vram_pin(adev);
-	if (r)
-		return r;
-
 	if (!amdgpu_emu_mode)
 		gfx_v10_0_init_golden_registers(adev);
 
@@ -3867,7 +3812,6 @@ static int gfx_v10_0_hw_fini(void *handle)
 	}
 	gfx_v10_0_cp_enable(adev, false);
 	gfx_v10_0_enable_gui_idle_interrupt(adev, false);
-	gfx_v10_0_csb_vram_unpin(adev);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index 791ba398f007..d92e92e5d50b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -4554,6 +4554,8 @@ static int gfx_v7_0_hw_init(void *handle)
 
 	gfx_v7_0_constants_init(adev);
 
+	/* init CSB */
+	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
 	/* init rlc */
 	r = adev->gfx.rlc.funcs->resume(adev);
 	if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index ffbde9136372..983db77999e7 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -1321,39 +1321,6 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
 	return 0;
 }
 
-static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev)
-{
-	int r;
-
-	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-	if (unlikely(r != 0))
-		return r;
-
-	r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
-			AMDGPU_GEM_DOMAIN_VRAM);
-	if (!r)
-		adev->gfx.rlc.clear_state_gpu_addr =
-			amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
-
-	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
-	return r;
-}
-
-static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev)
-{
-	int r;
-
-	if (!adev->gfx.rlc.clear_state_obj)
-		return;
-
-	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
-	if (likely(r == 0)) {
-		amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-	}
-}
-
 static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
 {
 	amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -3917,6 +3884,7 @@ static void gfx_v8_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
 
 static void gfx_v8_0_init_csb(struct amdgpu_device *adev)
 {
+	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
 	/* csib */
 	WREG32(mmRLC_CSIB_ADDR_HI,
 			adev->gfx.rlc.clear_state_gpu_addr >> 32);
@@ -4837,10 +4805,6 @@ static int gfx_v8_0_hw_init(void *handle)
 	gfx_v8_0_init_golden_registers(adev);
 	gfx_v8_0_constants_init(adev);
 
-	r = gfx_v8_0_csb_vram_pin(adev);
-	if (r)
-		return r;
-
 	r = adev->gfx.rlc.funcs->resume(adev);
 	if (r)
 		return r;
@@ -4958,8 +4922,6 @@ static int gfx_v8_0_hw_fini(void *handle)
 		pr_err("rlc is busy, skip halt rlc\n");
 	amdgpu_gfx_rlc_exit_safe_mode(adev);
 
-	gfx_v8_0_csb_vram_unpin(adev);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index faf2ffce5837..66328ffa395a 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -1695,39 +1695,6 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
 	return 0;
 }
 
-static int gfx_v9_0_csb_vram_pin(struct amdgpu_device *adev)
-{
-	int r;
-
-	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-	if (unlikely(r != 0))
-		return r;
-
-	r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj,
-			AMDGPU_GEM_DOMAIN_VRAM);
-	if (!r)
-		adev->gfx.rlc.clear_state_gpu_addr =
-			amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj);
-
-	amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
-	return r;
-}
-
-static void gfx_v9_0_csb_vram_unpin(struct amdgpu_device *adev)
-{
-	int r;
-
-	if (!adev->gfx.rlc.clear_state_obj)
-		return;
-
-	r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
-	if (likely(r == 0)) {
-		amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-		amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-	}
-}
-
 static void gfx_v9_0_mec_fini(struct amdgpu_device *adev)
 {
 	amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
@@ -2415,6 +2382,7 @@ static void gfx_v9_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
 
 static void gfx_v9_0_init_csb(struct amdgpu_device *adev)
 {
+	adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr);
 	/* csib */
 	WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_HI),
 			adev->gfx.rlc.clear_state_gpu_addr >> 32);
@@ -3706,10 +3674,6 @@ static int gfx_v9_0_hw_init(void *handle)
 
 	gfx_v9_0_constants_init(adev);
 
-	r = gfx_v9_0_csb_vram_pin(adev);
-	if (r)
-		return r;
-
 	r = adev->gfx.rlc.funcs->resume(adev);
 	if (r)
 		return r;
@@ -3791,8 +3755,6 @@ static int gfx_v9_0_hw_fini(void *handle)
 	gfx_v9_0_cp_enable(adev, false);
 	adev->gfx.rlc.funcs->stop(adev);
 
-	gfx_v9_0_csb_vram_unpin(adev);
-
 	return 0;
 }
 
commit fa2b93e39b1d167d342aecd6d3f53d9972405226
Author: Xiaojie Yuan <xiaojie.yuan at amd.com>
Date:   Wed Nov 6 21:10:20 2019 +0800

    drm/amdgpu/gfx10: unlock srbm_mutex after queue programming finish
    
    srbm_mutex is to guarantee atomicity for r/w of gfx indexed registers
    
    Signed-off-by: Xiaojie Yuan <xiaojie.yuan at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index ca5f0e7ea1ac..208fb9cd1482 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -2825,7 +2825,7 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
 	/* Init gfx ring 0 for pipe 0 */
 	mutex_lock(&adev->srbm_mutex);
 	gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID0);
-	mutex_unlock(&adev->srbm_mutex);
+
 	/* Set ring buffer size */
 	ring = &adev->gfx.gfx_ring[0];
 	rb_bufsz = order_base_2(ring->ring_size / 8);
@@ -2863,11 +2863,11 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
 	WREG32_SOC15(GC, 0, mmCP_RB_ACTIVE, 1);
 
 	gfx_v10_0_cp_gfx_set_doorbell(adev, ring);
+	mutex_unlock(&adev->srbm_mutex);
 
 	/* Init gfx ring 1 for pipe 1 */
 	mutex_lock(&adev->srbm_mutex);
 	gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID1);
-	mutex_unlock(&adev->srbm_mutex);
 	ring = &adev->gfx.gfx_ring[1];
 	rb_bufsz = order_base_2(ring->ring_size / 8);
 	tmp = REG_SET_FIELD(0, CP_RB1_CNTL, RB_BUFSZ, rb_bufsz);
@@ -2897,6 +2897,7 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
 	WREG32_SOC15(GC, 0, mmCP_RB1_ACTIVE, 1);
 
 	gfx_v10_0_cp_gfx_set_doorbell(adev, ring);
+	mutex_unlock(&adev->srbm_mutex);
 
 	/* Switch to pipe 0 */
 	mutex_lock(&adev->srbm_mutex);
commit f0312f45a0540a1551ca4644ff2461250520111a
Author: John Clements <john.clements at amd.com>
Date:   Mon Dec 2 17:57:25 2019 +0800

    drm/amdgpu: Added ASIC specific checks in gfxhub V1.1 get XGMI info
    
    Added max hive/node info checks per supported ASIC
    
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Signed-off-by: John Clements <john.clements at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c
index 5e9ab8eb214a..c0ab71df0d90 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c
@@ -33,16 +33,31 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
 	u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL);
 	u32 max_region =
 		REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION);
+	u32 max_num_physical_nodes   = 0;
+	u32 max_physical_node_id     = 0;
+
+	switch (adev->asic_type) {
+	case CHIP_VEGA20:
+		max_num_physical_nodes   = 4;
+		max_physical_node_id     = 3;
+		break;
+	case CHIP_ARCTURUS:
+		max_num_physical_nodes   = 8;
+		max_physical_node_id     = 7;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	/* PF_MAX_REGION=0 means xgmi is disabled */
 	if (max_region) {
 		adev->gmc.xgmi.num_physical_nodes = max_region + 1;
-		if (adev->gmc.xgmi.num_physical_nodes > 4)
+		if (adev->gmc.xgmi.num_physical_nodes > max_num_physical_nodes)
 			return -EINVAL;
 
 		adev->gmc.xgmi.physical_node_id =
 			REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_LFB_REGION);
-		if (adev->gmc.xgmi.physical_node_id > 3)
+		if (adev->gmc.xgmi.physical_node_id > max_physical_node_id)
 			return -EINVAL;
 		adev->gmc.xgmi.node_segment_size = REG_GET_FIELD(
 			RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE),
commit 76d8f83b2a6175909f4e93de868609d76fbba47c
Author: Likun Gao <Likun.Gao at amd.com>
Date:   Mon Dec 2 15:04:35 2019 +0800

    drm/amdgpu/powerplay: unify smu send message function
    
    Drop smu_send_smc_msg function from ASIC specify structure.
    Reuse smu_send_smc_msg_with_param function for smu_send_smc_msg.
    Set paramer to 0 for smu_send_msg function, otherwise it will send
    with previous paramer value (Not a certain value).
    Materialize msg type for smu send message function definition.
    
    Signed-off-by: Likun Gao <Likun.Gao at amd.com>
    Reviewed-by: Kevin Wang <kevin1.wang at amd.com>
    Reviewed-by: Evan Quan <evan.quan at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
index 40b546c75fc2..5ff7ccedfbed 100644
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
@@ -2548,3 +2548,12 @@ uint32_t smu_get_pptable_power_limit(struct smu_context *smu)
 
 	return ret;
 }
+
+int smu_send_smc_msg(struct smu_context *smu,
+		     enum smu_message_type msg)
+{
+	int ret;
+
+	ret = smu_send_smc_msg_with_param(smu, msg, 0);
+	return ret;
+}
diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
index 58c7c4a3053e..ce3566ca3e24 100644
--- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
@@ -2130,7 +2130,6 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
 	.set_tool_table_location = smu_v11_0_set_tool_table_location,
 	.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
 	.system_features_control = smu_v11_0_system_features_control,
-	.send_smc_msg = smu_v11_0_send_msg,
 	.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
 	.read_smc_arg = smu_v11_0_read_arg,
 	.init_display_count = smu_v11_0_init_display_count,
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index 031e0c22fcc7..ac9758305ab3 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -497,8 +497,8 @@ struct pptable_funcs {
 	int (*notify_memory_pool_location)(struct smu_context *smu);
 	int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu);
 	int (*system_features_control)(struct smu_context *smu, bool en);
-	int (*send_smc_msg)(struct smu_context *smu, uint16_t msg);
-	int (*send_smc_msg_with_param)(struct smu_context *smu, uint16_t msg, uint32_t param);
+	int (*send_smc_msg_with_param)(struct smu_context *smu,
+				       enum smu_message_type msg, uint32_t param);
 	int (*read_smc_arg)(struct smu_context *smu, uint32_t *arg);
 	int (*init_display_count)(struct smu_context *smu, uint32_t count);
 	int (*set_allowed_mask)(struct smu_context *smu);
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 606149085683..719844257713 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -177,10 +177,9 @@ int smu_v11_0_notify_memory_pool_location(struct smu_context *smu);
 int smu_v11_0_system_features_control(struct smu_context *smu,
 					     bool en);
 
-int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg);
-
 int
-smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v11_0_send_msg_with_param(struct smu_context *smu,
+			      enum smu_message_type msg,
 			      uint32_t param);
 
 int smu_v11_0_read_arg(struct smu_context *smu, uint32_t *arg);
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v12_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v12_0.h
index 9b9f5df0911c..9d81d789c713 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v12_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v12_0.h
@@ -44,10 +44,9 @@ int smu_v12_0_read_arg(struct smu_context *smu, uint32_t *arg);
 
 int smu_v12_0_wait_for_response(struct smu_context *smu);
 
-int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg);
-
 int
-smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v12_0_send_msg_with_param(struct smu_context *smu,
+			      enum smu_message_type msg,
 			      uint32_t param);
 
 int smu_v12_0_check_fw_status(struct smu_context *smu);
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index aaec884d63ed..4a14fd1f9fd5 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -2055,7 +2055,6 @@ static const struct pptable_funcs navi10_ppt_funcs = {
 	.set_tool_table_location = smu_v11_0_set_tool_table_location,
 	.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
 	.system_features_control = smu_v11_0_system_features_control,
-	.send_smc_msg = smu_v11_0_send_msg,
 	.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
 	.read_smc_arg = smu_v11_0_read_arg,
 	.init_display_count = smu_v11_0_init_display_count,
diff --git a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
index 04daf7e9fe05..977bdd962e98 100644
--- a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
@@ -697,7 +697,6 @@ static const struct pptable_funcs renoir_ppt_funcs = {
 	.check_fw_version = smu_v12_0_check_fw_version,
 	.powergate_sdma = smu_v12_0_powergate_sdma,
 	.powergate_vcn = smu_v12_0_powergate_vcn,
-	.send_smc_msg = smu_v12_0_send_msg,
 	.send_smc_msg_with_param = smu_v12_0_send_msg_with_param,
 	.read_smc_arg = smu_v12_0_read_arg,
 	.set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h
index 8bcda7871309..8872f8b2d502 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_internal.h
+++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h
@@ -75,8 +75,8 @@
 #define smu_set_default_od_settings(smu, initialize) \
 	((smu)->ppt_funcs->set_default_od_settings ? (smu)->ppt_funcs->set_default_od_settings((smu), (initialize)) : 0)
 
-#define smu_send_smc_msg(smu, msg) \
-	((smu)->ppt_funcs->send_smc_msg? (smu)->ppt_funcs->send_smc_msg((smu), (msg)) : 0)
+int smu_send_smc_msg(struct smu_context *smu, enum smu_message_type msg);
+
 #define smu_send_smc_msg_with_param(smu, msg, param) \
 	((smu)->ppt_funcs->send_smc_msg_with_param? (smu)->ppt_funcs->send_smc_msg_with_param((smu), (msg), (param)) : 0)
 #define smu_read_smc_arg(smu, arg) \
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index fc9679ea2368..e4268a627eff 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -90,36 +90,11 @@ static int smu_v11_0_wait_for_response(struct smu_context *smu)
 	return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
 }
 
-int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg)
-{
-	struct amdgpu_device *adev = smu->adev;
-	int ret = 0, index = 0;
-
-	index = smu_msg_get_index(smu, msg);
-	if (index < 0)
-		return index;
-
-	smu_v11_0_wait_for_response(smu);
-
-	WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
-
-	smu_v11_0_send_msg_without_waiting(smu, (uint16_t)index);
-
-	ret = smu_v11_0_wait_for_response(smu);
-
-	if (ret)
-		pr_err("failed send message: %10s (%d) response %#x\n",
-		       smu_get_message_name(smu, msg), index, ret);
-
-	return ret;
-
-}
-
 int
-smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v11_0_send_msg_with_param(struct smu_context *smu,
+			      enum smu_message_type msg,
 			      uint32_t param)
 {
-
 	struct amdgpu_device *adev = smu->adev;
 	int ret = 0, index = 0;
 
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
index 139dd737eaa5..094cfc46adac 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
@@ -77,33 +77,9 @@ int smu_v12_0_wait_for_response(struct smu_context *smu)
 	return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
 }
 
-int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg)
-{
-	struct amdgpu_device *adev = smu->adev;
-	int ret = 0, index = 0;
-
-	index = smu_msg_get_index(smu, msg);
-	if (index < 0)
-		return index;
-
-	smu_v12_0_wait_for_response(smu);
-
-	WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
-
-	smu_v12_0_send_msg_without_waiting(smu, (uint16_t)index);
-
-	ret = smu_v12_0_wait_for_response(smu);
-
-	if (ret)
-		pr_err("Failed to send message 0x%x, response 0x%x\n", index,
-		       ret);
-
-	return ret;
-
-}
-
 int
-smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
+smu_v12_0_send_msg_with_param(struct smu_context *smu,
+			      enum smu_message_type msg,
 			      uint32_t param)
 {
 	struct amdgpu_device *adev = smu->adev;
diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
index 0b4892833808..60b9ff097142 100644
--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
@@ -3231,7 +3231,6 @@ static const struct pptable_funcs vega20_ppt_funcs = {
 	.set_tool_table_location = smu_v11_0_set_tool_table_location,
 	.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
 	.system_features_control = smu_v11_0_system_features_control,
-	.send_smc_msg = smu_v11_0_send_msg,
 	.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
 	.read_smc_arg = smu_v11_0_read_arg,
 	.init_display_count = smu_v11_0_init_display_count,
commit 627f75d18910b287472593a4a2c41de9a386f5a2
Author: Alex Deucher <alexander.deucher at amd.com>
Date:   Fri Nov 15 10:02:44 2019 -0500

    drm/amd/display: re-enable wait in pipelock, but add timeout
    
    Removing this causes hangs in some games, so re-add it, but add
    a timeout so we don't hang while switching flip types.
    
    Bug: https://bugzilla.kernel.org/show_bug.cgi?id=205169
    Bug: https://bugs.freedesktop.org/show_bug.cgi?id=112266
    Reviewed-by: Harry Wentland <harry.wentland at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 921a36668ced..ac8c18fadefc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1037,6 +1037,25 @@ void dcn20_pipe_control_lock(
 	if (pipe->plane_state != NULL)
 		flip_immediate = pipe->plane_state->flip_immediate;
 
+	if (flip_immediate && lock) {
+		const int TIMEOUT_FOR_FLIP_PENDING = 100000;
+		int i;
+
+		for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
+			if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp))
+				break;
+			udelay(1);
+		}
+
+		if (pipe->bottom_pipe != NULL) {
+			for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
+				if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp))
+					break;
+				udelay(1);
+			}
+		}
+	}
+
 	/* In flip immediate and pipe splitting case, we need to use GSL
 	 * for synchronization. Only do setup on locking and on flip type change.
 	 */
commit 30c517736e1a31a3edcdbfc791c83bc565d437ca
Author: Zhan liu <zhan.liu at amd.com>
Date:   Mon Dec 2 15:12:27 2019 -0500

    drm/amd/display: Get NV14 specific ip params as needed
    
    [Why]
    NV14 is using its own ip params that's different from other
    DCN2.0 ASICs.
    
    [How]
    Add ASIC revision check to make sure NV14 gets correct
    ip params.
    
    Signed-off-by: Zhan Liu <zhan.liu at amd.com>
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 300a6392a1f0..09793336d84f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -3282,6 +3282,10 @@ static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
 static struct _vcs_dpi_ip_params_st *get_asic_rev_ip_params(
 	uint32_t hw_internal_rev)
 {
+	/* NV14 */
+	if (ASICREV_IS_NAVI14_M(hw_internal_rev))
+		return &dcn2_0_nv14_ip;
+
 	/* NV12 and NV10 */
 	return &dcn2_0_ip;
 }
commit 516fb68d9501460dc3e47d107daa9402b075b9fe
Author: Zhan liu <zhan.liu at amd.com>
Date:   Mon Dec 2 14:54:16 2019 -0500

    drm/amd/display: Adding NV14 IP Parameters
    
    [Why]
    NV14 IP Parameters are missing.
    
    [How]
    Add IP Parameters in.
    
    Signed-off-by: Zhan liu <zhan.liu at amd.com>
    Reviewed-by: Harry Wentland <harry.wentland at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 1d7d3fd33aab..300a6392a1f0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -157,6 +157,74 @@ struct _vcs_dpi_ip_params_st dcn2_0_ip = {
 	.xfc_fill_constant_bytes = 0,
 };
 
+struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
+	.odm_capable = 1,
+	.gpuvm_enable = 0,
+	.hostvm_enable = 0,
+	.gpuvm_max_page_table_levels = 4,
+	.hostvm_max_page_table_levels = 4,
+	.hostvm_cached_page_table_levels = 0,
+	.num_dsc = 5,
+	.rob_buffer_size_kbytes = 168,
+	.det_buffer_size_kbytes = 164,
+	.dpte_buffer_size_in_pte_reqs_luma = 84,
+	.dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
+	.dpp_output_buffer_pixels = 2560,
+	.opp_output_buffer_lines = 1,
+	.pixel_chunk_size_kbytes = 8,
+	.pte_enable = 1,
+	.max_page_table_levels = 4,
+	.pte_chunk_size_kbytes = 2,
+	.meta_chunk_size_kbytes = 2,
+	.writeback_chunk_size_kbytes = 2,
+	.line_buffer_size_bits = 789504,
+	.is_line_buffer_bpp_fixed = 0,
+	.line_buffer_fixed_bpp = 0,
+	.dcc_supported = true,
+	.max_line_buffer_lines = 12,
+	.writeback_luma_buffer_size_kbytes = 12,
+	.writeback_chroma_buffer_size_kbytes = 8,
+	.writeback_chroma_line_buffer_width_pixels = 4,
+	.writeback_max_hscl_ratio = 1,
+	.writeback_max_vscl_ratio = 1,
+	.writeback_min_hscl_ratio = 1,
+	.writeback_min_vscl_ratio = 1,
+	.writeback_max_hscl_taps = 12,
+	.writeback_max_vscl_taps = 12,
+	.writeback_line_buffer_luma_buffer_size = 0,
+	.writeback_line_buffer_chroma_buffer_size = 14643,
+	.cursor_buffer_size = 8,
+	.cursor_chunk_size = 2,
+	.max_num_otg = 5,
+	.max_num_dpp = 5,
+	.max_num_wb = 1,
+	.max_dchub_pscl_bw_pix_per_clk = 4,
+	.max_pscl_lb_bw_pix_per_clk = 2,
+	.max_lb_vscl_bw_pix_per_clk = 4,
+	.max_vscl_hscl_bw_pix_per_clk = 4,
+	.max_hscl_ratio = 8,
+	.max_vscl_ratio = 8,
+	.hscl_mults = 4,
+	.vscl_mults = 4,
+	.max_hscl_taps = 8,
+	.max_vscl_taps = 8,
+	.dispclk_ramp_margin_percent = 1,
+	.underscan_factor = 1.10,
+	.min_vblank_lines = 32, //
+	.dppclk_delay_subtotal = 77, //
+	.dppclk_delay_scl_lb_only = 16,
+	.dppclk_delay_scl = 50,
+	.dppclk_delay_cnvc_formatter = 8,
+	.dppclk_delay_cnvc_cursor = 6,
+	.dispclk_delay_subtotal = 87, //
+	.dcfclk_cstate_latency = 10, // SRExitTime
+	.max_inter_dcn_tile_repeaters = 8,
+	.xfc_supported = true,
+	.xfc_fill_bw_overhead_percent = 10.0,
+	.xfc_fill_constant_bytes = 0,
+	.ptoi_supported = 0
+};
+
 struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
 	/* Defaults that get patched on driver load from firmware. */
 	.clock_limits = {
commit c3d03c5a196f21381c1a2166a4648beba13d3d1f
Author: Zhan Liu <zhan.liu at amd.com>
Date:   Thu Nov 28 14:12:11 2019 -0500

    drm/amd/display: Include num_vmid and num_dsc within NV14's resource caps
    
    [Why]
    "num_vmid" and "num_dsc" are missing within NV14's resource caps structure.
    
    [How]
    Add the missing parts.
    
    Signed-off-by: Zhan Liu <zhan.liu at amd.com>
    Reviewed-by: Harry Wentland <harry.wentland at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index bbd1c98564be..1d7d3fd33aab 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -854,6 +854,8 @@ static const struct resource_caps res_cap_nv14 = {
 		.num_pll = 5,
 		.num_dwb = 1,
 		.num_ddc = 5,
+		.num_vmid = 16,
+		.num_dsc = 5,
 };
 
 static const struct dc_debug_options debug_defaults_drv = {
commit e2195f7d0e735b9e466873333a7e832e3b7d254b
Author: Monk Liu <Monk.Liu at amd.com>
Date:   Tue Nov 26 19:40:08 2019 +0800

    drm/amdgpu: use CPU to flush vmhub if sched stopped
    
    otherwse the flush_gpu_tlb will hang if we unload the
    KMD becuase the schedulers already stopped
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 321f8a997be8..232469507446 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -326,7 +326,8 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 
 	if (!adev->mman.buffer_funcs_enabled ||
 	    !adev->ib_pool_ready ||
-	    adev->in_gpu_reset) {
+	    adev->in_gpu_reset ||
+	    ring->sched.ready == false) {
 		gmc_v10_0_flush_vm_hub(adev, vmid, AMDGPU_GFXHUB_0, 0);
 		mutex_unlock(&adev->mman.gtt_window_lock);
 		return;
commit 01bb630319337be15fc50c211126180198d4e157
Author: Matt Roper <matthew.d.roper at intel.com>
Date:   Wed Nov 27 14:13:13 2019 -0800

    drm/i915/ehl: Make icp_digital_port_connected() use phy instead of port
    
    When looking at SDEISR to determine the connection status of combo
    outputs, we should use the phy index rather than the port index.
    Although they're usually the same thing, EHL's DDI-D (port D) is
    attached to PHY-A and SDEISR doesn't even have bits for a "D" output.
    It's also possible that future platforms may map DDIs (the internal
    display engine programming units) to PHYs (the output handling on the IO
    side) in ways where port!=phy, so let's look at the PHY index by
    default.
    
    v2: Rename to intel_combo_phy_connected.  (Lucas)
    
    Fixes: 719d24002602 ("drm/i915/ehl: Enable DDI-D")
    Cc: José Roberto de Souza <jose.souza at intel.com>
    Cc: Lucas De Marchi <lucas.demarchi at intel.com>
    Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
    Reviewed-by: Lucas De Marchi <lucas.demarchi at intel.com>
    Reviewed-by: José Roberto de Souza <jose.souza at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191127221314.575575-2-matthew.d.roper@intel.com
    (cherry picked from commit 3d1e388d4072dd240e558709d2f73605a742a723)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index c61ac0c3acb5..050655a1a3d8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5476,15 +5476,13 @@ static bool bxt_digital_port_connected(struct intel_encoder *encoder)
 	return I915_READ(GEN8_DE_PORT_ISR) & bit;
 }
 
-static bool icl_combo_port_connected(struct drm_i915_private *dev_priv,
-				     struct intel_digital_port *intel_dig_port)
+static bool intel_combo_phy_connected(struct drm_i915_private *dev_priv,
+				      enum phy phy)
 {
-	enum port port = intel_dig_port->base.port;
-
-	if (HAS_PCH_MCC(dev_priv) && port == PORT_C)
+	if (HAS_PCH_MCC(dev_priv) && phy == PHY_C)
 		return I915_READ(SDEISR) & SDE_TC_HOTPLUG_ICP(PORT_TC1);
 
-	return I915_READ(SDEISR) & SDE_DDI_HOTPLUG_ICP(port);
+	return I915_READ(SDEISR) & SDE_DDI_HOTPLUG_ICP(phy);
 }
 
 static bool icl_digital_port_connected(struct intel_encoder *encoder)
@@ -5494,7 +5492,7 @@ static bool icl_digital_port_connected(struct intel_encoder *encoder)
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (intel_phy_is_combo(dev_priv, phy))
-		return icl_combo_port_connected(dev_priv, dig_port);
+		return intel_combo_phy_connected(dev_priv, phy);
 	else if (intel_phy_is_tc(dev_priv, phy))
 		return intel_tc_port_connected(dig_port);
 	else
commit 4afaab78522f5ea96a1b1087fe9768f3af935ac2
Merge: 3ee1a9f5d0bc 92b1aa773fad
Author: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Date:   Mon Dec 2 12:17:25 2019 +0200

    Merge tag 'gvt-next-fixes-2019-12-02' of https://github.com/intel/gvt-linux into drm-intel-next-fixes
    
    gvt-next-fixes-2019-12-02
    
    - Fix cmd parser for MI_ATOMIC (Zhenyu)
    - Fix non-priv register access warning on CFL (Fred)
    
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    From: Zhenyu Wang <zhenyuw at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191202051711.GZ4196@zhen-hp.sh.intel.com

commit 3ee1a9f5d0bc0e9dbac5b014e2e8a7d540b836df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Nov 29 15:18:45 2019 +0000

    drm/i915/gem: Take timeline->mutex to walk list-of-requests
    
    Though the context is closed and so no more requests can be added to the
    timeline, retirement can still be removing requests. It can even be
    removing the very request we are inspecting and so cause us to wander
    into dead links.
    
    Serialise with the retirement by taking the timeline->mutex used for
    guarding the timeline->requests list.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112404
    Fixes: 4a3174152147 ("drm/i915/gem: Refine occupancy test in kill_context()")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
    Cc: Matthew Auld <matthew.auld at intel.com>
    Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191129151845.1092933-1-chris@chris-wilson.co.uk
    (cherry picked from commit 7ce596a8036cf3a4cb9ffa0c4edd8a76a7a43cc3)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 255ab040022e..4237a2887ff2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -368,7 +368,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
 	if (!ce->timeline)
 		return NULL;
 
-	rcu_read_lock();
+	mutex_lock(&ce->timeline->mutex);
 	list_for_each_entry_reverse(rq, &ce->timeline->requests, link) {
 		if (i915_request_completed(rq))
 			break;
@@ -378,7 +378,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
 		if (engine)
 			break;
 	}
-	rcu_read_unlock();
+	mutex_unlock(&ce->timeline->mutex);
 
 	return engine;
 }
commit 92b1aa773fadb4e2a90ed5d3beecb422d568ad9a
Author: Zhenyu Wang <zhenyuw at linux.intel.com>
Date:   Thu Nov 21 13:57:45 2019 +0800

    drm/i915/gvt: Fix cmd length check for MI_ATOMIC
    
    Correct valid command length check for MI_ATOMIC, need to check inline
    data available field instead of operand data length for whole command.
    
    Fixes: 00a33be40634 ("drm/i915/gvt: Add valid length check for MI variable commands")
    Reported-by: Alex Williamson <alex.williamson at redhat.com>
    Acked-by: Gao Fred <fred.gao at intel.com>
    Cc: stable at vger.kernel.org
    Signed-off-by: Zhenyu Wang <zhenyuw at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 6a3ac8cde95d..21a176cd8acc 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -1599,9 +1599,9 @@ static int cmd_handler_mi_op_2f(struct parser_exec_state *s)
 	if (!(cmd_val(s, 0) & (1 << 22)))
 		return ret;
 
-	/* check if QWORD */
-	if (DWORD_FIELD(0, 20, 19) == 1)
-		valid_len += 8;
+	/* check inline data */
+	if (cmd_val(s, 0) & BIT(18))
+		valid_len = CMD_LEN(9);
 	ret = gvt_check_valid_cmd_length(cmd_length(s),
 			valid_len);
 	if (ret)
commit 3e25dbca8b75d3cc7dbbfd7aaaa0d29c730d45ac
Merge: 36a170b1ca0d 3cc44feb9861
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Dec 2 10:23:06 2019 +1000

    Merge tag 'drm-intel-next-fixes-2019-11-28' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
    
    - Important fix to uAPI alignment on query IOCTL
    - Fixes for the power regression introduced by the previous security patches
    - Avoid regressing super heavy benchmarks by increasing the default request pre-emption timeout from 100 ms to 640 ms to
    - Resulting set of smaller fixes done while problem was inspected
    - Display fixes for EHL voltage level programming and TGL DKL PHY vswing for HDMI
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191128141524.GA11992@jlahtine-desk.ger.corp.intel.com

commit 36a170b1ca0da12641b1d847524f17b4aa2a2283
Merge: acc61b892936 e20c9284c8f2
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Dec 2 10:14:35 2019 +1000

    Merge tag 'drm-msm-next-2019-11-05' of https://gitlab.freedesktop.org/drm/msm into drm-next
    
    + OCMEM support to enable the couple generations that had shared OCMEM
      rather than GMEM exclusively for the GPU (late a3xx and I think basically
      all of a4xx).  Bjorn and Brian decided to land this through the drm
      tree to avoid having to coordinate merge requests.
    + a510 support, and various associated display support
    + the usual misc cleanups and fixes
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Rob Clark <robdclark at gmail.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/ <CAF6AEGv-JWswEJRxe5AmnGQO1SZnpxK05kO1E29K6UUzC9GMMw at mail.gmail.com

commit 3cc44feb9861d2f5267af9b962ae92c5ea1b48fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 26 06:55:21 2019 +0000

    drm/i915: Reduce nested prepare_remote_context() to a trylock
    
    On context retiring, we may invoke the kernel_context to unpin this
    context. Elsewhere, we may use the kernel_context to modify this
    context. This currently leads to an AB-BA lock inversion, so we need to
    back-off from the contended lock, and repeat.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111732
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191126065521.2331017-1-chris@chris-wilson.co.uk
    (cherry picked from commit 58b4c1a07ada7fb91ea757bdb9bd47df02207357)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index ee9d2bcd2c13..ef7bc41ffffa 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -310,10 +310,23 @@ int intel_context_prepare_remote_request(struct intel_context *ce,
 	GEM_BUG_ON(rq->hw_context == ce);
 
 	if (rcu_access_pointer(rq->timeline) != tl) { /* timeline sharing! */
-		err = mutex_lock_interruptible_nested(&tl->mutex,
-						      SINGLE_DEPTH_NESTING);
-		if (err)
-			return err;
+		/*
+		 * Ideally, we just want to insert our foreign fence as
+		 * a barrier into the remove context, such that this operation
+		 * occurs after all current operations in that context, and
+		 * all future operations must occur after this.
+		 *
+		 * Currently, the timeline->last_request tracking is guarded
+		 * by its mutex and so we must obtain that to atomically
+		 * insert our barrier. However, since we already hold our
+		 * timeline->mutex, we must be careful against potential
+		 * inversion if we are the kernel_context as the remote context
+		 * will itself poke at the kernel_context when it needs to
+		 * unpin. Ergo, if already locked, we drop both locks and
+		 * try again (through the magic of userspace repeating EAGAIN).
+		 */
+		if (!mutex_trylock(&tl->mutex))
+			return -EAGAIN;
 
 		/* Queue this switch after current activity by this context. */
 		err = i915_active_fence_set(&tl->last_request, rq);
commit 8d15ede5cc6b66d5176856060b94196bc3382283
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 25 16:27:37 2019 +0000

    drm/i915: Default to a more lenient forced preemption timeout
    
    Based on a sampling of a number of benchmarks across platforms, by
    default opt for a much more lenient timeout so that we should not
    adversely affect existing "good" clients.
    
    640ms ought to be enough for anyone.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112169
    Fixes: 3a7a92aba8fb ("drm/i915/execlists: Force preemption")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Cc: Eero Tamminen <eero.t.tamminen at intel.com>
    Cc: Dmitry Rogozhkin <dmitry.v.rogozhkin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191125162737.2161069-1-chris@chris-wilson.co.uk
    (cherry picked from commit 5766a5ffc6a69595903865518c43636bde0e4ac4)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/Kconfig.profile b/drivers/gpu/drm/i915/Kconfig.profile
index 1799537a3228..c280b6ae38eb 100644
--- a/drivers/gpu/drm/i915/Kconfig.profile
+++ b/drivers/gpu/drm/i915/Kconfig.profile
@@ -25,7 +25,7 @@ config DRM_I915_HEARTBEAT_INTERVAL
 
 config DRM_I915_PREEMPT_TIMEOUT
 	int "Preempt timeout (ms, jiffy granularity)"
-	default 100 # milliseconds
+	default 640 # milliseconds
 	help
 	  How long to wait (in milliseconds) for a preemption event to occur
 	  when submitting a new context via execlists. If the current context
commit 1591fadf857cdbaf2baa55e421af99a61354713c
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Nov 26 11:15:29 2019 +0100

    drm/mgag200: Add workaround for HW that does not support 'startadd'
    
    There's at least one system that does not interpret the value of
    the device's 'startadd' field correctly, which leads to incorrectly
    displayed scanout buffers. Always placing the active scanout buffer
    at offset 0 works around the problem.
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Reported-by: John Donnelly <john.p.donnelly at oracle.com>
    Tested-by: John Donnelly <john.p.donnelly at oracle.com>
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Fixes: 81da87f63a1e ("drm: Replace drm_gem_vram_push_to_system() with kunmap + unpin")
    Cc: Gerd Hoffmann <kraxel at redhat.com>
    Cc: Dave Airlie <airlied at redhat.com>
    Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Cc: Maxime Ripard <mripard at kernel.org>
    Cc: David Airlie <airlied at linux.ie>
    Cc: Sam Ravnborg <sam at ravnborg.org>
    Cc: "Y.C. Chen" <yc_chen at aspeedtech.com>
    Cc: Neil Armstrong <narmstrong at baylibre.com>
    Cc: Thomas Gleixner <tglx at linutronix.de>
    Cc: "José Roberto de Souza" <jose.souza at intel.com>
    Cc: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
    Cc: dri-devel at lists.freedesktop.org
    Cc: <stable at vger.kernel.org> # v5.3+
    Link: https://gitlab.freedesktop.org/drm/misc/issues/7
    Link: https://patchwork.freedesktop.org/patch/msgid/20191126101529.20356-4-tzimmermann@suse.de

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 397f8b0a9af8..d43951caeea0 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -30,6 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400);
 static struct drm_driver driver;
 
 static const struct pci_device_id pciidlist[] = {
+	{ PCI_VENDOR_ID_MATROX, 0x522, PCI_VENDOR_ID_SUN, 0x4852, 0, 0,
+		G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
 	{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A },
 	{ PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
 	{ PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
@@ -60,6 +62,35 @@ static void mga_pci_remove(struct pci_dev *pdev)
 
 DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);
 
+static bool mgag200_pin_bo_at_0(const struct mga_device *mdev)
+{
+	return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD;
+}
+
+int mgag200_driver_dumb_create(struct drm_file *file,
+			       struct drm_device *dev,
+			       struct drm_mode_create_dumb *args)
+{
+	struct mga_device *mdev = dev->dev_private;
+	unsigned long pg_align;
+
+	if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
+		return -EINVAL;
+
+	pg_align = 0ul;
+
+	/*
+	 * Aligning scanout buffers to the size of the video ram forces
+	 * placement at offset 0. Works around a bug where HW does not
+	 * respect 'startadd' field.
+	 */
+	if (mgag200_pin_bo_at_0(mdev))
+		pg_align = PFN_UP(mdev->mc.vram_size);
+
+	return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev,
+					     pg_align, false, args);
+}
+
 static struct drm_driver driver = {
 	.driver_features = DRIVER_GEM | DRIVER_MODESET,
 	.load = mgag200_driver_load,
@@ -71,7 +102,10 @@ static struct drm_driver driver = {
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
-	DRM_GEM_VRAM_DRIVER
+	.debugfs_init = drm_vram_mm_debugfs_init,
+	.dumb_create = mgag200_driver_dumb_create,
+	.dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset,
+	.gem_prime_mmap = drm_gem_prime_mmap,
 };
 
 static struct pci_driver mgag200_pci_driver = {
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 4b4f9ce74a84..aa32aad222c2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -150,6 +150,9 @@ enum mga_type {
 	G200_EW3,
 };
 
+/* HW does not handle 'startadd' field correct. */
+#define MGAG200_FLAG_HW_BUG_NO_STARTADD	(1ul << 8)
+
 #define MGAG200_TYPE_MASK	(0x000000ff)
 #define MGAG200_FLAG_MASK	(0x00ffff00)
 
commit d6d437d97d54c85a1a93967b2745e31dff03365a
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Nov 26 11:15:28 2019 +0100

    drm/mgag200: Store flags from PCI driver data in device structure
    
    The flags field in struct mga_device has been unused so far. We now
    use it to store flag bits from the PCI driver.
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Fixes: 81da87f63a1e ("drm: Replace drm_gem_vram_push_to_system() with kunmap + unpin")
    Cc: John Donnelly <john.p.donnelly at oracle.com>
    Cc: Gerd Hoffmann <kraxel at redhat.com>
    Cc: Dave Airlie <airlied at redhat.com>
    Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Cc: Maxime Ripard <mripard at kernel.org>
    Cc: David Airlie <airlied at linux.ie>
    Cc: Sam Ravnborg <sam at ravnborg.org>
    Cc: "Y.C. Chen" <yc_chen at aspeedtech.com>
    Cc: Neil Armstrong <narmstrong at baylibre.com>
    Cc: Thomas Gleixner <tglx at linutronix.de>
    Cc: "José Roberto de Souza" <jose.souza at intel.com>
    Cc: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
    Cc: dri-devel at lists.freedesktop.org
    Cc: <stable at vger.kernel.org> # v5.3+
    Link: https://patchwork.freedesktop.org/patch/msgid/20191126101529.20356-3-tzimmermann@suse.de

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 976404634092..4b4f9ce74a84 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -151,6 +151,7 @@ enum mga_type {
 };
 
 #define MGAG200_TYPE_MASK	(0x000000ff)
+#define MGAG200_FLAG_MASK	(0x00ffff00)
 
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
@@ -188,6 +189,13 @@ mgag200_type_from_driver_data(kernel_ulong_t driver_data)
 {
 	return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
 }
+
+static inline unsigned long
+mgag200_flags_from_driver_data(kernel_ulong_t driver_data)
+{
+	return driver_data & MGAG200_FLAG_MASK;
+}
+
 				/* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 void mgag200_modeset_fini(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 517c5693ad69..e1bc5b0aa774 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -94,6 +94,7 @@ static int mgag200_device_init(struct drm_device *dev,
 	struct mga_device *mdev = dev->dev_private;
 	int ret, option;
 
+	mdev->flags = mgag200_flags_from_driver_data(flags);
 	mdev->type = mgag200_type_from_driver_data(flags);
 
 	/* Hardcode the number of CRTCs to 1 */
commit 3a8a5aba142a44eaeba0cb0ec1b4a8f177b5e59a
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Nov 26 11:15:27 2019 +0100

    drm/mgag200: Extract device type from flags
    
    Adds a conversion function that extracts the device type from the
    PCI id-table flags. Allows for storing additional information in the
    other flag bits.
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Fixes: 81da87f63a1e ("drm: Replace drm_gem_vram_push_to_system() with kunmap + unpin")
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Cc: John Donnelly <john.p.donnelly at oracle.com>
    Cc: Gerd Hoffmann <kraxel at redhat.com>
    Cc: Dave Airlie <airlied at redhat.com>
    Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Cc: Maxime Ripard <mripard at kernel.org>
    Cc: David Airlie <airlied at linux.ie>
    Cc: Sam Ravnborg <sam at ravnborg.org>
    Cc: Emil Velikov <emil.velikov at collabora.com>
    Cc: "Y.C. Chen" <yc_chen at aspeedtech.com>
    Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
    Cc: "José Roberto de Souza" <jose.souza at intel.com>
    Cc: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
    Cc: dri-devel at lists.freedesktop.org
    Cc: <stable at vger.kernel.org> # v5.3+
    Link: https://patchwork.freedesktop.org/patch/msgid/20191126101529.20356-2-tzimmermann@suse.de

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 0ea9a525e57d..976404634092 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -150,6 +150,8 @@ enum mga_type {
 	G200_EW3,
 };
 
+#define MGAG200_TYPE_MASK	(0x000000ff)
+
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
 struct mga_device {
@@ -181,6 +183,11 @@ struct mga_device {
 	u32 unique_rev_id;
 };
 
+static inline enum mga_type
+mgag200_type_from_driver_data(kernel_ulong_t driver_data)
+{
+	return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
+}
 				/* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 void mgag200_modeset_fini(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 5f74aabcd3df..517c5693ad69 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -94,7 +94,7 @@ static int mgag200_device_init(struct drm_device *dev,
 	struct mga_device *mdev = dev->dev_private;
 	int ret, option;
 
-	mdev->type = flags;
+	mdev->type = mgag200_type_from_driver_data(flags);
 
 	/* Hardcode the number of CRTCs to 1 */
 	mdev->num_crtc = 1;
commit 68421940b0d66f3806bfd0cd0f78a6935c75cb55
Author: Gao, Fred <fred.gao at intel.com>
Date:   Wed Nov 27 00:08:29 2019 +0800

    drm/i915/gvt: Update force-to-nonpriv register whitelist
    
    Host print below warning message when creating guest:
        "gvt: vgpu(1) Invalid FORCE_NONPRIV write 10002349".
    
    Add register 0x2348 in force-to-nonpriv whitelist as required
    by guest.
    
    Signed-off-by: Gao, Fred <fred.gao at intel.com>
    Reviewed-by: Zhenyu Wang <zhenyuw at linux.intel.com>
    Signed-off-by: Zhenyu Wang <zhenyuw at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 4f8a25e760f0..bb9fe6bf5275 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -460,6 +460,7 @@ static int pipeconf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 static i915_reg_t force_nonpriv_white_list[] = {
 	GEN9_CS_DEBUG_MODE1, //_MMIO(0x20ec)
 	GEN9_CTX_PREEMPT_REG,//_MMIO(0x2248)
+	PS_INVOCATION_COUNT,//_MMIO(0x2348)
 	GEN8_CS_CHICKEN1,//_MMIO(0x2580)
 	_MMIO(0x2690),
 	_MMIO(0x2694),
commit aeab9eda04cd412791551eaad036143eec04e648
Author: Gao, Fred <fred.gao at intel.com>
Date:   Wed Nov 27 00:07:35 2019 +0800

    drm/i915/gvt: Refine non privilege register address calucation
    
    The BitField of non privilege register address is only from bit 2 to 25.
    
    v2: use REG_GENMASK instead. (Zhenyu)
    
    Signed-off-by: Gao, Fred <fred.gao at intel.com>
    Reviewed-by: Zhenyu Wang <zhenyuw at linux.intel.com>
    Signed-off-by: Zhenyu Wang <zhenyuw at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index bd12af349123..4f8a25e760f0 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -508,7 +508,7 @@ static inline bool in_whitelist(unsigned int reg)
 static int force_nonpriv_write(struct intel_vgpu *vgpu,
 	unsigned int offset, void *p_data, unsigned int bytes)
 {
-	u32 reg_nonpriv = *(u32 *)p_data;
+	u32 reg_nonpriv = (*(u32 *)p_data) & REG_GENMASK(25, 2);
 	int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
 	u32 ring_base;
 	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
@@ -528,7 +528,7 @@ static int force_nonpriv_write(struct intel_vgpu *vgpu,
 			bytes);
 	} else
 		gvt_err("vgpu(%d) Invalid FORCE_NONPRIV write %x at offset %x\n",
-			vgpu->id, reg_nonpriv, offset);
+			vgpu->id, *(u32 *)p_data, offset);
 
 	return 0;
 }
commit c38402fe6c4dbb235bef405209c2195ee9cd679c
Author: Timothy Pearson <tpearson at raptorengineering.com>
Date:   Sun Nov 24 13:15:16 2019 -0600

    amdgpu: Enable KFD on POWER systems
    
    KFD has been verified to function on POWER systems (Talos II / Vega 64).
    It should be available as a kernel configuration option on these systems.
    
    Signed-off-by: Timothy Pearson <tpearson at raptorengineering.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdkfd/Kconfig b/drivers/gpu/drm/amd/amdkfd/Kconfig
index a1a35d4d594b..ba0e68057a89 100644
--- a/drivers/gpu/drm/amd/amdkfd/Kconfig
+++ b/drivers/gpu/drm/amd/amdkfd/Kconfig
@@ -5,7 +5,7 @@
 
 config HSA_AMD
 	bool "HSA kernel driver for AMD GPU devices"
-	depends on DRM_AMDGPU && (X86_64 || ARM64)
+	depends on DRM_AMDGPU && (X86_64 || ARM64 || PPC64)
 	imply AMD_IOMMU_V2 if X86_64
 	select MMU_NOTIFIER
 	help
commit 29a39c90baaa1d8f28123932d3ea1bbe7c22f325
Author: Felix Kuehling <Felix.Kuehling at amd.com>
Date:   Mon Jul 15 16:18:03 2019 -0400

    drm/amdgpu: Optimize KFD page table reservation
    
    Be less pessimistic about estimated page table use for KFD. Most
    allocations use 2MB pages and therefore need less VRAM for page
    tables. This allows more VRAM to be used for applications especially
    on large systems with many GPUs and hundreds of GB of system memory.
    
    Example: 8 GPUs with 32GB VRAM each + 256GB system memory = 512GB
    Old page table reservation per GPU:  1GB
    New page table reservation per GPU: 32MB
    
    Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
    Reviewed-by: xinhui pan <xinhui.pan at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index ae6f5446262c..12dbcfaa34b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -105,11 +105,24 @@ void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
 		(kfd_mem_limit.max_ttm_mem_limit >> 20));
 }
 
+/* Estimate page table size needed to represent a given memory size
+ *
+ * With 4KB pages, we need one 8 byte PTE for each 4KB of memory
+ * (factor 512, >> 9). With 2MB pages, we need one 8 byte PTE for 2MB
+ * of memory (factor 256K, >> 18). ROCm user mode tries to optimize
+ * for 2MB pages for TLB efficiency. However, small allocations and
+ * fragmented system memory still need some 4KB pages. We choose a
+ * compromise that should work in most cases without reserving too
+ * much memory for page tables unnecessarily (factor 16K, >> 14).
+ */
+#define ESTIMATE_PT_SIZE(mem_size) ((mem_size) >> 14)
+
 static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
 		uint64_t size, u32 domain, bool sg)
 {
+	uint64_t reserved_for_pt =
+		ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
 	size_t acc_size, system_mem_needed, ttm_mem_needed, vram_needed;
-	uint64_t reserved_for_pt = amdgpu_amdkfd_total_mem_size >> 9;
 	int ret = 0;
 
 	acc_size = ttm_bo_dma_acc_size(&adev->mman.bdev, size,
commit dea8b900293df57b6545bc195b50bbb649fe9741
Author: Alex Deucher <alexander.deucher at amd.com>
Date:   Mon Nov 25 11:11:18 2019 -0500

    drm/amdgpu: flag vram lost on baco reset for VI/CIK
    
    VI/CIK BACO was inflight when this fix landed for SOC15/NV.
    Add the fix to VI/CIK as well.
    
    Acked-by: Evan Quan <evan.quan at amd.com>
    Acked-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 2d64d270725d..b22a10b2d201 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1346,10 +1346,13 @@ static int cik_asic_reset(struct amdgpu_device *adev)
 {
 	int r;
 
-	if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
+	if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
+		if (!adev->in_suspend)
+			amdgpu_inc_vram_lost(adev);
 		r = smu7_asic_baco_reset(adev);
-	else
+	} else {
 		r = cik_asic_pci_config_reset(adev);
+	}
 
 	return r;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 78e5cdc0c058..f1b171e30774 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -783,10 +783,13 @@ static int vi_asic_reset(struct amdgpu_device *adev)
 {
 	int r;
 
-	if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
+	if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
+		if (!adev->in_suspend)
+			amdgpu_inc_vram_lost(adev);
 		r = smu7_asic_baco_reset(adev);
-	else
+	} else {
 		r = vi_asic_pci_config_reset(adev);
+	}
 
 	return r;
 }
commit a0c2a84ddaf176425d2e0285ae46d4b6057d047d
Author: Alex Deucher <alexander.deucher at amd.com>
Date:   Fri Nov 22 14:16:55 2019 -0500

    MAINTAINERS: Drop Rex Zhu for amdgpu powerplay
    
    No longer works on the driver.
    
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Evan Quan <evan.quan at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index 741e3f433f6e..71c4ca8b278f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -856,7 +856,6 @@ S:	Maintained
 F:	drivers/i2c/busses/i2c-amd-mp2*
 
 AMD POWERPLAY
-M:	Rex Zhu <rex.zhu at amd.com>
 M:	Evan Quan <evan.quan at amd.com>
 L:	amd-gfx at lists.freedesktop.org
 S:	Supported
commit 5985ebbe78bba0058429c1482442aa64d14c1ce2
Author: John Clements <john.clements at amd.com>
Date:   Mon Nov 25 18:24:17 2019 +0800

    drm/amdgpu: Resolved offchip EEPROM I/O issue
    
    Updated target I2C address
    
    Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
    Signed-off-by: John Clements <john.clements at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
index 7de16c0c2f20..2a8e04895595 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
@@ -27,7 +27,8 @@
 #include <linux/bits.h>
 #include "smu_v11_0_i2c.h"
 
-#define EEPROM_I2C_TARGET_ADDR 0xA0
+#define EEPROM_I2C_TARGET_ADDR_ARCTURUS  0xA8
+#define EEPROM_I2C_TARGET_ADDR_VEGA20    0xA0
 
 /*
  * The 2 macros bellow represent the actual size in bytes that
@@ -83,7 +84,7 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
 {
 	int ret = 0;
 	struct i2c_msg msg = {
-			.addr	= EEPROM_I2C_TARGET_ADDR,
+			.addr	= 0,
 			.flags	= 0,
 			.len	= EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE,
 			.buf	= buff,
@@ -93,6 +94,8 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
 	*(uint16_t *)buff = EEPROM_HDR_START;
 	__encode_table_header_to_buff(&control->tbl_hdr, buff + EEPROM_ADDRESS_SIZE);
 
+	msg.addr = control->i2c_address;
+
 	ret = i2c_transfer(&control->eeprom_accessor, &msg, 1);
 	if (ret < 1)
 		DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret);
@@ -203,7 +206,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
 	unsigned char buff[EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE] = { 0 };
 	struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr;
 	struct i2c_msg msg = {
-			.addr	= EEPROM_I2C_TARGET_ADDR,
+			.addr	= 0,
 			.flags	= I2C_M_RD,
 			.len	= EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE,
 			.buf	= buff,
@@ -213,10 +216,12 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
 
 	switch (adev->asic_type) {
 	case CHIP_VEGA20:
+		control->i2c_address = EEPROM_I2C_TARGET_ADDR_VEGA20;
 		ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor);
 		break;
 
 	case CHIP_ARCTURUS:
+		control->i2c_address = EEPROM_I2C_TARGET_ADDR_ARCTURUS;
 		ret = smu_i2c_eeprom_init(&adev->smu, &control->eeprom_accessor);
 		break;
 
@@ -229,6 +234,8 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
 		return ret;
 	}
 
+	msg.addr = control->i2c_address;
+
 	/* Read/Create table header from EEPROM address 0 */
 	ret = i2c_transfer(&control->eeprom_accessor, &msg, 1);
 	if (ret < 1) {
@@ -408,8 +415,8 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
 		 * Update bits 16,17 of EEPROM address in I2C address by setting them
 		 * to bits 1,2 of Device address byte
 		 */
-		msg->addr = EEPROM_I2C_TARGET_ADDR |
-			       ((control->next_addr & EEPROM_ADDR_MSB_MASK) >> 15);
+		msg->addr = control->i2c_address |
+			        ((control->next_addr & EEPROM_ADDR_MSB_MASK) >> 15);
 		msg->flags	= write ? 0 : I2C_M_RD;
 		msg->len	= EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE;
 		msg->buf	= buff;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
index 622269957c1b..ca78f812d436 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
@@ -50,6 +50,7 @@ struct amdgpu_ras_eeprom_control {
 	struct mutex tbl_mutex;
 	bool bus_locked;
 	uint32_t tbl_byte_sum;
+	uint16_t i2c_address; // 8-bit represented address
 };
 
 /*
commit 946621691f9919c263b4679b77f81f06019d3636
Author: Alex Deucher <alexander.deucher at amd.com>
Date:   Tue Nov 19 15:54:17 2019 -0500

    drm/amd/display: add default clocks if not able to fetch them
    
    dm_pp_get_clock_levels_by_type needs to add the default clocks
    to the powerplay case as well.  This was accidently dropped.
    
    Fixes: b3ea88fef321de ("drm/amd/powerplay: add get_clock_by_type interface for display")
    Bug: https://gitlab.freedesktop.org/drm/amd/issues/906
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index 55a520a63712..778f186b3a05 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -342,7 +342,8 @@ bool dm_pp_get_clock_levels_by_type(
 	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
 		if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
 			dc_to_pp_clock_type(clk_type), &pp_clks)) {
-		/* Error in pplib. Provide default values. */
+			/* Error in pplib. Provide default values. */
+			get_default_clock_levels(clk_type, dc_clks);
 			return true;
 		}
 	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type) {
commit 0725d9a31869e6c80630e99da366ede2848295cc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 18 23:02:40 2019 +0000

    drm/i915/gt: Make intel_ring_unpin() safe for concurrent pint
    
    In order to avoid some nasty mutex inversions, commit 09c5ab384f6f
    ("drm/i915: Keep rings pinned while the context is active") allowed the
    intel_ring unpinning to be run concurrently with the next context
    pinning it. Thus each step in intel_ring_unpin() needed to be atomic and
    ordered in a nice onion with intel_ring_pin() so that the lifetimes
    overlapped and were always safe.
    
    Sadly, a few steps in intel_ring_unpin() were overlooked, such as
    closing the read/write pointers of the ring and discarding the
    intel_ring.vaddr, as these steps were not serialised with
    intel_ring_pin() and so could leave the ring in disarray.
    
    Fixes: 09c5ab384f6f ("drm/i915: Keep rings pinned while the context is active")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191118230254.2615942-6-chris@chris-wilson.co.uk
    (cherry picked from commit a266bf42006004306dd48a9082c35dfbff153307)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c
index ece20504d240..374b28f13ca0 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -57,9 +57,10 @@ int intel_ring_pin(struct intel_ring *ring)
 
 	i915_vma_make_unshrinkable(vma);
 
-	GEM_BUG_ON(ring->vaddr);
-	ring->vaddr = addr;
+	/* Discard any unused bytes beyond that submitted to hw. */
+	intel_ring_reset(ring, ring->emit);
 
+	ring->vaddr = addr;
 	return 0;
 
 err_ring:
@@ -85,20 +86,14 @@ void intel_ring_unpin(struct intel_ring *ring)
 	if (!atomic_dec_and_test(&ring->pin_count))
 		return;
 
-	/* Discard any unused bytes beyond that submitted to hw. */
-	intel_ring_reset(ring, ring->emit);
-
 	i915_vma_unset_ggtt_write(vma);
 	if (i915_vma_is_map_and_fenceable(vma))
 		i915_vma_unpin_iomap(vma);
 	else
 		i915_gem_object_unpin_map(vma->obj);
 
-	GEM_BUG_ON(!ring->vaddr);
-	ring->vaddr = NULL;
-
-	i915_vma_unpin(vma);
 	i915_vma_make_purgeable(vma);
+	i915_vma_unpin(vma);
 }
 
 static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
commit 311770173fac27845a3a83e2c16100a54d308f72
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 25 10:58:58 2019 +0000

    drm/i915/gt: Schedule request retirement when timeline idles
    
    The major drawback of commit 7e34f4e4aad3 ("drm/i915/gen8+: Add RC6 CTX
    corruption WA") is that it disables RC6 while Skylake (and friends) is
    active, and we do not consider the GPU idle until all outstanding
    requests have been retired and the engine switched over to the kernel
    context. If userspace is idle, this task falls onto our background idle
    worker, which only runs roughly once a second, meaning that userspace has
    to have been idle for a couple of seconds before we enable RC6 again.
    Naturally, this causes us to consume considerably more energy than
    before as powersaving is effectively disabled while a display server
    (here's looking at you Xorg) is running.
    
    As execlists will get a completion event as each context is completed,
    we can use this interrupt to queue a retire worker bound to this engine
    to cleanup idle timelines. We will then immediately notice the idle
    engine (without userspace intervention or the aid of the background
    retire worker) and start parking the GPU. Thus during light workloads,
    we will do much more work to idle the GPU faster...  Hopefully with
    commensurate power saving!
    
    v2: Watch context completions and only look at those local to the engine
    when retiring to reduce the amount of excess work we perform.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112315
    References: 7e34f4e4aad3 ("drm/i915/gen8+: Add RC6 CTX corruption WA")
    References: 2248a28384fe ("drm/i915/gen8+: Add RC6 CTX corruption WA")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191125105858.1718307-3-chris@chris-wilson.co.uk
    (cherry picked from commit 4f88f8747fa43c97c3b3712d8d87295ea757cc51)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 5ca3ec911e50..813bd3a610d2 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -28,13 +28,13 @@
 
 #include "i915_drv.h"
 
-#include "gt/intel_gt.h"
-
+#include "intel_context.h"
 #include "intel_engine.h"
 #include "intel_engine_pm.h"
 #include "intel_engine_pool.h"
 #include "intel_engine_user.h"
-#include "intel_context.h"
+#include "intel_gt.h"
+#include "intel_gt_requests.h"
 #include "intel_lrc.h"
 #include "intel_reset.h"
 #include "intel_ring.h"
@@ -616,6 +616,7 @@ static int intel_engine_setup_common(struct intel_engine_cs *engine)
 	intel_engine_init_execlists(engine);
 	intel_engine_init_cmd_parser(engine);
 	intel_engine_init__pm(engine);
+	intel_engine_init_retire(engine);
 
 	intel_engine_pool_init(&engine->pool);
 
@@ -838,6 +839,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
 
 	cleanup_status_page(engine);
 
+	intel_engine_fini_retire(engine);
 	intel_engine_pool_fini(&engine->pool);
 	intel_engine_fini_breadcrumbs(engine);
 	intel_engine_cleanup_cmd_parser(engine);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 758f0e8ec672..17f1f1441efc 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -451,6 +451,14 @@ struct intel_engine_cs {
 
 	struct intel_engine_execlists execlists;
 
+	/*
+	 * Keep track of completed timelines on this engine for early
+	 * retirement with the goal of quickly enabling powersaving as
+	 * soon as the engine is idle.
+	 */
+	struct intel_timeline *retire;
+	struct work_struct retire_work;
+
 	/* status_notifier: list of callbacks for context-switch changes */
 	struct atomic_notifier_head context_status_notifier;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
index a0112ba08ca7..3dc13ecf41bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
@@ -4,6 +4,8 @@
  * Copyright © 2019 Intel Corporation
  */
 
+#include <linux/workqueue.h>
+
 #include "i915_drv.h" /* for_each_engine() */
 #include "i915_request.h"
 #include "intel_gt.h"
@@ -29,6 +31,79 @@ static void flush_submission(struct intel_gt *gt)
 		intel_engine_flush_submission(engine);
 }
 
+static void engine_retire(struct work_struct *work)
+{
+	struct intel_engine_cs *engine =
+		container_of(work, typeof(*engine), retire_work);
+	struct intel_timeline *tl = xchg(&engine->retire, NULL);
+
+	do {
+		struct intel_timeline *next = xchg(&tl->retire, NULL);
+
+		/*
+		 * Our goal here is to retire _idle_ timelines as soon as
+		 * possible (as they are idle, we do not expect userspace
+		 * to be cleaning up anytime soon).
+		 *
+		 * If the timeline is currently locked, either it is being
+		 * retired elsewhere or about to be!
+		 */
+		if (mutex_trylock(&tl->mutex)) {
+			retire_requests(tl);
+			mutex_unlock(&tl->mutex);
+		}
+		intel_timeline_put(tl);
+
+		GEM_BUG_ON(!next);
+		tl = ptr_mask_bits(next, 1);
+	} while (tl);
+}
+
+static bool add_retire(struct intel_engine_cs *engine,
+		       struct intel_timeline *tl)
+{
+	struct intel_timeline *first;
+
+	/*
+	 * We open-code a llist here to include the additional tag [BIT(0)]
+	 * so that we know when the timeline is already on a
+	 * retirement queue: either this engine or another.
+	 *
+	 * However, we rely on that a timeline can only be active on a single
+	 * engine at any one time and that add_retire() is called before the
+	 * engine releases the timeline and transferred to another to retire.
+	 */
+
+	if (READ_ONCE(tl->retire)) /* already queued */
+		return false;
+
+	intel_timeline_get(tl);
+	first = READ_ONCE(engine->retire);
+	do
+		tl->retire = ptr_pack_bits(first, 1, 1);
+	while (!try_cmpxchg(&engine->retire, &first, tl));
+
+	return !first;
+}
+
+void intel_engine_add_retire(struct intel_engine_cs *engine,
+			     struct intel_timeline *tl)
+{
+	if (add_retire(engine, tl))
+		schedule_work(&engine->retire_work);
+}
+
+void intel_engine_init_retire(struct intel_engine_cs *engine)
+{
+	INIT_WORK(&engine->retire_work, engine_retire);
+}
+
+void intel_engine_fini_retire(struct intel_engine_cs *engine)
+{
+	flush_work(&engine->retire_work);
+	GEM_BUG_ON(engine->retire);
+}
+
 long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 {
 	struct intel_gt_timelines *timelines = &gt->timelines;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.h b/drivers/gpu/drm/i915/gt/intel_gt_requests.h
index bd31cbce47e0..d626fb115386 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.h
@@ -7,7 +7,9 @@
 #ifndef INTEL_GT_REQUESTS_H
 #define INTEL_GT_REQUESTS_H
 
+struct intel_engine_cs;
 struct intel_gt;
+struct intel_timeline;
 
 long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout);
 static inline void intel_gt_retire_requests(struct intel_gt *gt)
@@ -15,6 +17,11 @@ static inline void intel_gt_retire_requests(struct intel_gt *gt)
 	intel_gt_retire_requests_timeout(gt, 0);
 }
 
+void intel_engine_init_retire(struct intel_engine_cs *engine);
+void intel_engine_add_retire(struct intel_engine_cs *engine,
+			     struct intel_timeline *tl);
+void intel_engine_fini_retire(struct intel_engine_cs *engine);
+
 int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);
 
 void intel_gt_init_requests(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 217b32ae0bcc..9fdefbdc3546 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -142,6 +142,7 @@
 #include "intel_engine_pm.h"
 #include "intel_gt.h"
 #include "intel_gt_pm.h"
+#include "intel_gt_requests.h"
 #include "intel_lrc_reg.h"
 #include "intel_mocs.h"
 #include "intel_reset.h"
@@ -1115,6 +1116,14 @@ __execlists_schedule_out(struct i915_request *rq,
 	 * refrain from doing non-trivial work here.
 	 */
 
+	/*
+	 * If we have just completed this context, the engine may now be
+	 * idle and we want to re-enter powersaving.
+	 */
+	if (list_is_last(&rq->link, &ce->timeline->requests) &&
+	    i915_request_completed(rq))
+		intel_engine_add_retire(engine, ce->timeline);
+
 	intel_engine_context_out(engine);
 	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
 	intel_gt_pm_put_async(engine->gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index 839de6b9aa24..649798c184fb 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -282,6 +282,7 @@ void intel_timeline_fini(struct intel_timeline *timeline)
 {
 	GEM_BUG_ON(atomic_read(&timeline->pin_count));
 	GEM_BUG_ON(!list_empty(&timeline->requests));
+	GEM_BUG_ON(timeline->retire);
 
 	if (timeline->hwsp_cacheline)
 		cacheline_free(timeline->hwsp_cacheline);
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline_types.h b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
index 5244615ed1cb..aaf15cbe1ce1 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
@@ -66,6 +66,9 @@ struct intel_timeline {
 	 */
 	struct i915_active_fence last_request;
 
+	/** A chain of completed timelines ready for early retirement. */
+	struct intel_timeline *retire;
+
 	/**
 	 * We track the most recent seqno that we wait on in every context so
 	 * that we only have to emit a new await and dependency on a more
commit a09c2860ae4fcf4d7e25202661f3eb868547cddb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 25 10:58:57 2019 +0000

    drm/i915/gt: Adapt engine_park synchronisation rules for engine_retire
    
    In the next patch, we will introduce a new asynchronous retirement
    worker, fed by execlists CS events. Here we may queue a retirement as
    soon as a request is submitted to HW (and completes instantly), and we
    also want to process that retirement as early as possible and cannot
    afford to postpone (as there may not be another opportunity to retire it
    for a few seconds). To allow the new async retirer to run in parallel
    with our submission, pull the __i915_request_queue (that passes the
    request to HW) inside the timelines spinlock so that the retirement
    cannot release the timeline before we have completed the submission.
    
    v2: Actually to play nicely with engine_retire, we have to raise the
    timeline.active_lock before releasing the HW. intel_gt_retire_requsts()
    is still serialised by the outer lock so they cannot see this
    intermediate state, and engine_retire is serialised by HW submission.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191125105858.1718307-2-chris@chris-wilson.co.uk
    (cherry picked from commit 88a4655e75ac8f55eea5e3f38b176cba9cf653b5)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 373a4b9f159c..0e1ad4a4bd97 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -74,16 +74,33 @@ static inline void __timeline_mark_unlock(struct intel_context *ce,
 #endif /* !IS_ENABLED(CONFIG_LOCKDEP) */
 
 static void
-__intel_timeline_enter_and_release_pm(struct intel_timeline *tl,
-				      struct intel_engine_cs *engine)
+__queue_and_release_pm(struct i915_request *rq,
+		       struct intel_timeline *tl,
+		       struct intel_engine_cs *engine)
 {
 	struct intel_gt_timelines *timelines = &engine->gt->timelines;
 
+	GEM_TRACE("%s\n", engine->name);
+
+	/*
+	 * We have to serialise all potential retirement paths with our
+	 * submission, as we don't want to underflow either the
+	 * engine->wakeref.counter or our timeline->active_count.
+	 *
+	 * Equally, we cannot allow a new submission to start until
+	 * after we finish queueing, nor could we allow that submitter
+	 * to retire us before we are ready!
+	 */
 	spin_lock(&timelines->lock);
 
+	/* Let intel_gt_retire_requests() retire us (acquired under lock) */
 	if (!atomic_fetch_inc(&tl->active_count))
 		list_add_tail(&tl->link, &timelines->active_list);
 
+	/* Hand the request over to HW and so engine_retire() */
+	__i915_request_queue(rq, NULL);
+
+	/* Let new submissions commence (and maybe retire this timeline) */
 	__intel_wakeref_defer_park(&engine->wakeref);
 
 	spin_unlock(&timelines->lock);
@@ -148,10 +165,8 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 	rq->sched.attr.priority = I915_PRIORITY_BARRIER;
 	__i915_request_commit(rq);
 
-	__i915_request_queue(rq, NULL);
-
-	/* Expose ourselves to intel_gt_retire_requests() and new submission */
-	__intel_timeline_enter_and_release_pm(ce->timeline, engine);
+	/* Expose ourselves to the world */
+	__queue_and_release_pm(rq, ce->timeline, engine);
 
 	result = false;
 out_unlock:
commit 4ec5cc78c1b06f8d30b5c682acccf17fb5191cf2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 25 11:25:20 2019 +0000

    drm/i915/execlists: Fixup cancel_port_requests()
    
    I rushed a last minute correction to cancel_port_requests() to prevent
    the snooping of *execlists->active as the inflight array was being
    updated, without noticing we iterated the inflight array starting from
    active! Oops.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112387
    Fixes: 97f9af78f38d ("drm/i915/gt: Mark the execlists->active as the primary volatile access")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Andi Shyti <andi.shyti at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191125112520.1760492-1-chris@chris-wilson.co.uk
    (cherry picked from commit da0ef77e1e0ccff703efee82406c629d5c4f4bbb)
    [Joonas: Fixed Fixes: tag to match drm-intel-next-fixes]
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index a692e6c9ea75..217b32ae0bcc 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1937,19 +1937,17 @@ skip_submit:
 static void
 cancel_port_requests(struct intel_engine_execlists * const execlists)
 {
-	struct i915_request * const *port, *rq;
+	struct i915_request * const *port;
 
-	for (port = execlists->pending; (rq = *port); port++)
-		execlists_schedule_out(rq);
+	for (port = execlists->pending; *port; port++)
+		execlists_schedule_out(*port);
 	memset(execlists->pending, 0, sizeof(execlists->pending));
 
 	/* Mark the end of active before we overwrite *active */
-	WRITE_ONCE(execlists->active, execlists->pending);
-
-	for (port = execlists->active; (rq = *port); port++)
-		execlists_schedule_out(rq);
-	execlists->active =
-		memset(execlists->inflight, 0, sizeof(execlists->inflight));
+	for (port = xchg(&execlists->active, execlists->pending); *port; port++)
+		execlists_schedule_out(*port);
+	WRITE_ONCE(execlists->active,
+		   memset(execlists->inflight, 0, sizeof(execlists->inflight)));
 }
 
 static inline void
commit 97f9af78f38d43cd058cfd40220647be67aca9f7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 25 09:43:18 2019 +0000

    drm/i915/gt: Mark the execlists->active as the primary volatile access
    
    Since we want to do a lockless read of the current active request, and
    that request is written to by process_csb also without serialisation, we
    need to instruct gcc to take care in reading the pointer itself.
    
    Otherwise, we have observed execlists_active() to report 0x40.
    
    [ 2400.760381] igt/para-4098    1..s. 2376479300us : process_csb: rcs0 cs-irq head=3, tail=4
    [ 2400.760826] igt/para-4098    1..s. 2376479303us : process_csb: rcs0 csb[4]: status=0x00000001:0x00000000
    [ 2400.761271] igt/para-4098    1..s. 2376479306us : trace_ports: rcs0: promote { b9c59:2622, b9c55:2624 }
    [ 2400.761726] igt/para-4097    0d... 2376479311us : __i915_schedule: rcs0: -2147483648->3, inflight:0000000000000040, rq:ffff888208c1e940
    
    which is impossible!
    
    The answer is that as we keep the existing execlists->active pointing
    into the array as we copy over that array, the unserialised read may see
    a partial pointer value.
    
    Fixes: df403069029d ("drm/i915/execlists: Lift process_csb() out of the irq-off spinlock")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191125094318.1630806-1-chris@chris-wilson.co.uk
    (cherry picked from commit 331bf90591573dfe6c8e892239713ef9702f1396)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index bc3b72bfa9e3..01765a7ec18f 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -100,9 +100,7 @@ execlists_num_ports(const struct intel_engine_execlists * const execlists)
 static inline struct i915_request *
 execlists_active(const struct intel_engine_execlists *execlists)
 {
-	GEM_BUG_ON(execlists->active - execlists->inflight >
-		   execlists_num_ports(execlists));
-	return READ_ONCE(*execlists->active);
+	return *READ_ONCE(execlists->active);
 }
 
 static inline void
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 37fe72aa8e27..a692e6c9ea75 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1943,6 +1943,9 @@ cancel_port_requests(struct intel_engine_execlists * const execlists)
 		execlists_schedule_out(rq);
 	memset(execlists->pending, 0, sizeof(execlists->pending));
 
+	/* Mark the end of active before we overwrite *active */
+	WRITE_ONCE(execlists->active, execlists->pending);
+
 	for (port = execlists->active; (rq = *port); port++)
 		execlists_schedule_out(rq);
 	execlists->active =
@@ -2099,23 +2102,27 @@ static void process_csb(struct intel_engine_cs *engine)
 		else
 			promote = gen8_csb_parse(execlists, buf + 2 * head);
 		if (promote) {
+			struct i915_request * const *old = execlists->active;
+
+			/* Point active to the new ELSP; prevent overwriting */
+			WRITE_ONCE(execlists->active, execlists->pending);
+			set_timeslice(engine);
+
 			if (!inject_preempt_hang(execlists))
 				ring_set_paused(engine, 0);
 
 			/* cancel old inflight, prepare for switch */
-			trace_ports(execlists, "preempted", execlists->active);
-			while (*execlists->active)
-				execlists_schedule_out(*execlists->active++);
+			trace_ports(execlists, "preempted", old);
+			while (*old)
+				execlists_schedule_out(*old++);
 
 			/* switch pending to inflight */
 			GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
-			execlists->active =
-				memcpy(execlists->inflight,
-				       execlists->pending,
-				       execlists_num_ports(execlists) *
-				       sizeof(*execlists->pending));
-
-			set_timeslice(engine);
+			WRITE_ONCE(execlists->active,
+				   memcpy(execlists->inflight,
+					  execlists->pending,
+					  execlists_num_ports(execlists) *
+					  sizeof(*execlists->pending)));
 
 			WRITE_ONCE(execlists->pending[0], NULL);
 		} else {
commit bf201f5eda23eb57f7217d20ea3e18da8cbcf52b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 20 16:55:14 2019 +0000

    drm/i915/gt: Unlock engine-pm after queuing the kernel context switch
    
    In commit a79ca656b648 ("drm/i915: Push the wakeref->count deferral to
    the backend"), I erroneously concluded that we last modify the engine
    inside __i915_request_commit() meaning that we could enable concurrent
    submission for userspace as we enqueued this request. However, this
    falls into a trap with other users of the engine->kernel_context waking
    up and submitting their request before the idle-switch is queued, with
    the result that the kernel_context is executed out-of-sequence most
    likely upsetting the GPU and certainly ourselves when we try to retire
    the out-of-sequence requests.
    
    As such we need to hold onto the effective engine->kernel_context mutex
    lock (via the engine pm mutex proxy) until we have finish queuing the
    request to the engine.
    
    v2: Serialise against concurrent intel_gt_retire_requests()
    v3: Describe the hairy locking scheme with intel_gt_retire_requests()
    for future reference.
    v4: Combine timeline->lock and engine pm release; it's hairy.
    
    Fixes: a79ca656b648 ("drm/i915: Push the wakeref->count deferral to the backend")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191120165514.3955081-2-chris@chris-wilson.co.uk
    (cherry picked from commit 5cba288466e9b229feb68295675246e7522fb5eb)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 7269c87c1372..373a4b9f159c 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -73,8 +73,25 @@ static inline void __timeline_mark_unlock(struct intel_context *ce,
 
 #endif /* !IS_ENABLED(CONFIG_LOCKDEP) */
 
+static void
+__intel_timeline_enter_and_release_pm(struct intel_timeline *tl,
+				      struct intel_engine_cs *engine)
+{
+	struct intel_gt_timelines *timelines = &engine->gt->timelines;
+
+	spin_lock(&timelines->lock);
+
+	if (!atomic_fetch_inc(&tl->active_count))
+		list_add_tail(&tl->link, &timelines->active_list);
+
+	__intel_wakeref_defer_park(&engine->wakeref);
+
+	spin_unlock(&timelines->lock);
+}
+
 static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 {
+	struct intel_context *ce = engine->kernel_context;
 	struct i915_request *rq;
 	unsigned long flags;
 	bool result = true;
@@ -98,16 +115,31 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 	 * This should hold true as we can only park the engine after
 	 * retiring the last request, thus all rings should be empty and
 	 * all timelines idle.
+	 *
+	 * For unlocking, there are 2 other parties and the GPU who have a
+	 * stake here.
+	 *
+	 * A new gpu user will be waiting on the engine-pm to start their
+	 * engine_unpark. New waiters are predicated on engine->wakeref.count
+	 * and so intel_wakeref_defer_park() acts like a mutex_unlock of the
+	 * engine->wakeref.
+	 *
+	 * The other party is intel_gt_retire_requests(), which is walking the
+	 * list of active timelines looking for completions. Meanwhile as soon
+	 * as we call __i915_request_queue(), the GPU may complete our request.
+	 * Ergo, if we put ourselves on the timelines.active_list
+	 * (se intel_timeline_enter()) before we increment the
+	 * engine->wakeref.count, we may see the request completion and retire
+	 * it causing an undeflow of the engine->wakeref.
 	 */
-	flags = __timeline_mark_lock(engine->kernel_context);
+	flags = __timeline_mark_lock(ce);
+	GEM_BUG_ON(atomic_read(&ce->timeline->active_count) < 0);
 
-	rq = __i915_request_create(engine->kernel_context, GFP_NOWAIT);
+	rq = __i915_request_create(ce, GFP_NOWAIT);
 	if (IS_ERR(rq))
 		/* Context switch failed, hope for the best! Maybe reset? */
 		goto out_unlock;
 
-	intel_timeline_enter(i915_request_timeline(rq));
-
 	/* Check again on the next retirement. */
 	engine->wakeref_serial = engine->serial + 1;
 	i915_request_add_active_barriers(rq);
@@ -116,13 +148,14 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 	rq->sched.attr.priority = I915_PRIORITY_BARRIER;
 	__i915_request_commit(rq);
 
-	/* Release our exclusive hold on the engine */
-	__intel_wakeref_defer_park(&engine->wakeref);
 	__i915_request_queue(rq, NULL);
 
+	/* Expose ourselves to intel_gt_retire_requests() and new submission */
+	__intel_timeline_enter_and_release_pm(ce->timeline, engine);
+
 	result = false;
 out_unlock:
-	__timeline_mark_unlock(engine->kernel_context, flags);
+	__timeline_mark_unlock(ce, flags);
 	return result;
 }
 
commit ca1711d1991f968d1e88725a2e607e57ecd5c5f1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 20 16:55:13 2019 +0000

    drm/i915/gt: Close race between engine_park and intel_gt_retire_requests
    
    The general concept was that intel_timeline.active_count was locked by
    the intel_timeline.mutex. The exception was for power management, where
    the engine->kernel_context->timeline could be manipulated under the
    global wakeref.mutex.
    
    This was quite solid, as we always manipulated the timeline only while
    we held an engine wakeref.
    
    And then we started retiring requests outside of struct_mutex, only
    using the timelines.active_list and the timeline->mutex. There we
    started manipulating intel_timeline.active_count outside of an engine
    wakeref, and so introduced a race between __engine_park() and
    intel_gt_retire_requests(), a race that could result in the
    engine->kernel_context not being added to the active timelines and so
    losing requests, which caused us to keep the system permanently powered
    up [and unloadable].
    
    The race would be easy to close if we could take the engine wakeref for
    the timeline before we retire -- except timelines are not bound to any
    engine and so we would need to keep all active engines awake. The
    alternative is to guard intel_timeline_enter/intel_timeline_exit for use
    outside of the timeline->mutex.
    
    Fixes: e5dadff4b093 ("drm/i915: Protect request retirement with timeline->mutex")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Matthew Auld <matthew.auld at intel.com>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191120165514.3955081-1-chris@chris-wilson.co.uk
    (cherry picked from commit a6edbca74b305adc165e67065d7ee766006e6a48)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
index 353809ac2754..a0112ba08ca7 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
@@ -52,8 +52,8 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 		}
 
 		intel_timeline_get(tl);
-		GEM_BUG_ON(!tl->active_count);
-		tl->active_count++; /* pin the list element */
+		GEM_BUG_ON(!atomic_read(&tl->active_count));
+		atomic_inc(&tl->active_count); /* pin the list element */
 		spin_unlock_irqrestore(&timelines->lock, flags);
 
 		if (timeout > 0) {
@@ -74,7 +74,7 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 
 		/* Resume iteration after dropping lock */
 		list_safe_reset_next(tl, tn, link);
-		if (!--tl->active_count)
+		if (atomic_dec_and_test(&tl->active_count))
 			list_del(&tl->link);
 		else
 			active_count += !!rcu_access_pointer(tl->last_request.fence);
@@ -83,7 +83,7 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
 
 		/* Defer the final release to after the spinlock */
 		if (refcount_dec_and_test(&tl->kref.refcount)) {
-			GEM_BUG_ON(tl->active_count);
+			GEM_BUG_ON(atomic_read(&tl->active_count));
 			list_add(&tl->link, &free);
 		}
 	}
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index 14ad10acd548..839de6b9aa24 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -339,15 +339,33 @@ void intel_timeline_enter(struct intel_timeline *tl)
 	struct intel_gt_timelines *timelines = &tl->gt->timelines;
 	unsigned long flags;
 
+	/*
+	 * Pretend we are serialised by the timeline->mutex.
+	 *
+	 * While generally true, there are a few exceptions to the rule
+	 * for the engine->kernel_context being used to manage power
+	 * transitions. As the engine_park may be called from under any
+	 * timeline, it uses the power mutex as a global serialisation
+	 * lock to prevent any other request entering its timeline.
+	 *
+	 * The rule is generally tl->mutex, otherwise engine->wakeref.mutex.
+	 *
+	 * However, intel_gt_retire_request() does not know which engine
+	 * it is retiring along and so cannot partake in the engine-pm
+	 * barrier, and there we use the tl->active_count as a means to
+	 * pin the timeline in the active_list while the locks are dropped.
+	 * Ergo, as that is outside of the engine-pm barrier, we need to
+	 * use atomic to manipulate tl->active_count.
+	 */
 	lockdep_assert_held(&tl->mutex);
-
 	GEM_BUG_ON(!atomic_read(&tl->pin_count));
-	if (tl->active_count++)
+
+	if (atomic_add_unless(&tl->active_count, 1, 0))
 		return;
-	GEM_BUG_ON(!tl->active_count); /* overflow? */
 
 	spin_lock_irqsave(&timelines->lock, flags);
-	list_add(&tl->link, &timelines->active_list);
+	if (!atomic_fetch_inc(&tl->active_count))
+		list_add_tail(&tl->link, &timelines->active_list);
 	spin_unlock_irqrestore(&timelines->lock, flags);
 }
 
@@ -356,14 +374,16 @@ void intel_timeline_exit(struct intel_timeline *tl)
 	struct intel_gt_timelines *timelines = &tl->gt->timelines;
 	unsigned long flags;
 
+	/* See intel_timeline_enter() */
 	lockdep_assert_held(&tl->mutex);
 
-	GEM_BUG_ON(!tl->active_count);
-	if (--tl->active_count)
+	GEM_BUG_ON(!atomic_read(&tl->active_count));
+	if (atomic_add_unless(&tl->active_count, -1, 1))
 		return;
 
 	spin_lock_irqsave(&timelines->lock, flags);
-	list_del(&tl->link);
+	if (atomic_dec_and_test(&tl->active_count))
+		list_del(&tl->link);
 	spin_unlock_irqrestore(&timelines->lock, flags);
 
 	/*
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline_types.h b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
index 98d9ee166379..5244615ed1cb 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
@@ -42,7 +42,7 @@ struct intel_timeline {
 	 * from the intel_context caller plus internal atomicity.
 	 */
 	atomic_t pin_count;
-	unsigned int active_count;
+	atomic_t active_count;
 
 	const u32 *hwsp_seqno;
 	struct i915_vma *hwsp_ggtt;
commit ee33baa83109612d9a31fc2c2a7b74967767b358
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 20 12:54:33 2019 +0000

    drm/i915: Mark up the calling context for intel_wakeref_put()
    
    Previously, we assumed we could use mutex_trylock() within an atomic
    context, falling back to a worker if contended. However, such trickery
    is illegal inside interrupt context, and so we need to always use a
    worker under such circumstances. As we normally are in process context,
    we can typically use a plain mutex, and only defer to a work when we
    know we are being called from an interrupt path.
    
    Fixes: 51fbd8de87dc ("drm/i915/pmu: Atomically acquire the gt_pm wakeref")
    References: a0855d24fc22d ("locking/mutex: Complain upon mutex API misuse in IRQ contexts")
    References: https://bugs.freedesktop.org/show_bug.cgi?id=111626
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191120125433.3767149-1-chris@chris-wilson.co.uk
    (cherry picked from commit 07779a76ee1f93f930cf697b22be73d16e14f50c)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 3c0f490ff2c7..7269c87c1372 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -177,7 +177,8 @@ static int __engine_park(struct intel_wakeref *wf)
 
 	engine->execlists.no_priolist = false;
 
-	intel_gt_pm_put(engine->gt);
+	/* While gt calls i915_vma_parked(), we have to break the lock cycle */
+	intel_gt_pm_put_async(engine->gt);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
index 739c50fefcef..24e20344dc22 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
@@ -31,6 +31,16 @@ static inline void intel_engine_pm_put(struct intel_engine_cs *engine)
 	intel_wakeref_put(&engine->wakeref);
 }
 
+static inline void intel_engine_pm_put_async(struct intel_engine_cs *engine)
+{
+	intel_wakeref_put_async(&engine->wakeref);
+}
+
+static inline void intel_engine_pm_flush(struct intel_engine_cs *engine)
+{
+	intel_wakeref_unlock_wait(&engine->wakeref);
+}
+
 void intel_engine_init__pm(struct intel_engine_cs *engine);
 
 #endif /* INTEL_ENGINE_PM_H */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index 7917cc348375..a459a42ad5c2 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -105,7 +105,6 @@ static int __gt_park(struct intel_wakeref *wf)
 static const struct intel_wakeref_ops wf_ops = {
 	.get = __gt_unpark,
 	.put = __gt_park,
-	.flags = INTEL_WAKEREF_PUT_ASYNC,
 };
 
 void intel_gt_pm_init_early(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index b3e17399be9b..990efc27a4e4 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -32,6 +32,11 @@ static inline void intel_gt_pm_put(struct intel_gt *gt)
 	intel_wakeref_put(&gt->wakeref);
 }
 
+static inline void intel_gt_pm_put_async(struct intel_gt *gt)
+{
+	intel_wakeref_put_async(&gt->wakeref);
+}
+
 static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
 {
 	return intel_wakeref_wait_for_idle(&gt->wakeref);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 0ac3b26674ad..37fe72aa8e27 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1117,7 +1117,7 @@ __execlists_schedule_out(struct i915_request *rq,
 
 	intel_engine_context_out(engine);
 	execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
-	intel_gt_pm_put(engine->gt);
+	intel_gt_pm_put_async(engine->gt);
 
 	/*
 	 * If this is part of a virtual engine, its next request may
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index f03e000051c1..c97423a76642 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1114,7 +1114,7 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg)
 out:
 	intel_engine_cancel_stop_cs(engine);
 	reset_finish_engine(engine);
-	intel_engine_pm_put(engine);
+	intel_engine_pm_put_async(engine);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
index 20b9c83f43ad..cbf6b0735272 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
@@ -51,11 +51,12 @@ static int live_engine_pm(void *arg)
 				pr_err("intel_engine_pm_get_if_awake(%s) failed under %s\n",
 				       engine->name, p->name);
 			else
-				intel_engine_pm_put(engine);
-			intel_engine_pm_put(engine);
+				intel_engine_pm_put_async(engine);
+			intel_engine_pm_put_async(engine);
 			p->critical_section_end();
 
-			/* engine wakeref is sync (instant) */
+			intel_engine_pm_flush(engine);
+
 			if (intel_engine_pm_is_awake(engine)) {
 				pr_err("%s is still awake after flushing pm\n",
 				       engine->name);
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 5448f37c8102..dca15ace88f6 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -672,12 +672,13 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 	 * populated by i915_request_add_active_barriers() to point to the
 	 * request that will eventually release them.
 	 */
-	spin_lock_irqsave_nested(&ref->tree_lock, flags, SINGLE_DEPTH_NESTING);
 	llist_for_each_safe(pos, next, take_preallocated_barriers(ref)) {
 		struct active_node *node = barrier_from_ll(pos);
 		struct intel_engine_cs *engine = barrier_to_engine(node);
 		struct rb_node **p, *parent;
 
+		spin_lock_irqsave_nested(&ref->tree_lock, flags,
+					 SINGLE_DEPTH_NESTING);
 		parent = NULL;
 		p = &ref->tree.rb_node;
 		while (*p) {
@@ -693,12 +694,12 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 		}
 		rb_link_node(&node->node, parent, p);
 		rb_insert_color(&node->node, &ref->tree);
+		spin_unlock_irqrestore(&ref->tree_lock, flags);
 
 		GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
 		llist_add(barrier_to_ll(node), &engine->barrier_tasks);
 		intel_engine_pm_put(engine);
 	}
-	spin_unlock_irqrestore(&ref->tree_lock, flags);
 }
 
 void i915_request_add_active_barriers(struct i915_request *rq)
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 0d40dccd1409..2814218c5ba1 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -190,7 +190,7 @@ static u64 get_rc6(struct intel_gt *gt)
 	val = 0;
 	if (intel_gt_pm_get_if_awake(gt)) {
 		val = __get_rc6(gt);
-		intel_gt_pm_put(gt);
+		intel_gt_pm_put_async(gt);
 	}
 
 	spin_lock_irqsave(&pmu->lock, flags);
@@ -343,7 +343,7 @@ engines_sample(struct intel_gt *gt, unsigned int period_ns)
 
 skip:
 		spin_unlock_irqrestore(&engine->uncore->lock, flags);
-		intel_engine_pm_put(engine);
+		intel_engine_pm_put_async(engine);
 	}
 }
 
@@ -368,7 +368,7 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns)
 		if (intel_gt_pm_get_if_awake(gt)) {
 			val = intel_uncore_read_notrace(uncore, GEN6_RPSTAT1);
 			val = intel_get_cagf(rps, val);
-			intel_gt_pm_put(gt);
+			intel_gt_pm_put_async(gt);
 		}
 
 		add_sample_mult(&pmu->sample[__I915_SAMPLE_FREQ_ACT],
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index ad26d7f4ca3d..59aa1b6f1827 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -54,7 +54,8 @@ int __intel_wakeref_get_first(struct intel_wakeref *wf)
 
 static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
 {
-	if (!atomic_dec_and_test(&wf->count))
+	INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
+	if (unlikely(!atomic_dec_and_test(&wf->count)))
 		goto unlock;
 
 	/* ops->put() must reschedule its own release on error/deferral */
@@ -67,13 +68,12 @@ unlock:
 	mutex_unlock(&wf->mutex);
 }
 
-void __intel_wakeref_put_last(struct intel_wakeref *wf)
+void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags)
 {
 	INTEL_WAKEREF_BUG_ON(work_pending(&wf->work));
 
 	/* Assume we are not in process context and so cannot sleep. */
-	if (wf->ops->flags & INTEL_WAKEREF_PUT_ASYNC ||
-	    !mutex_trylock(&wf->mutex)) {
+	if (flags & INTEL_WAKEREF_PUT_ASYNC || !mutex_trylock(&wf->mutex)) {
 		schedule_work(&wf->work);
 		return;
 	}
diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h
index affe4de3746b..da6e8fd506e6 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.h
+++ b/drivers/gpu/drm/i915/intel_wakeref.h
@@ -9,6 +9,7 @@
 
 #include <linux/atomic.h>
 #include <linux/bits.h>
+#include <linux/lockdep.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
 #include <linux/stackdepot.h>
@@ -29,9 +30,6 @@ typedef depot_stack_handle_t intel_wakeref_t;
 struct intel_wakeref_ops {
 	int (*get)(struct intel_wakeref *wf);
 	int (*put)(struct intel_wakeref *wf);
-
-	unsigned long flags;
-#define INTEL_WAKEREF_PUT_ASYNC BIT(0)
 };
 
 struct intel_wakeref {
@@ -57,7 +55,7 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 } while (0)
 
 int __intel_wakeref_get_first(struct intel_wakeref *wf);
-void __intel_wakeref_put_last(struct intel_wakeref *wf);
+void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags);
 
 /**
  * intel_wakeref_get: Acquire the wakeref
@@ -100,10 +98,9 @@ intel_wakeref_get_if_active(struct intel_wakeref *wf)
 }
 
 /**
- * intel_wakeref_put: Release the wakeref
- * @i915: the drm_i915_private device
+ * intel_wakeref_put_flags: Release the wakeref
  * @wf: the wakeref
- * @fn: callback for releasing the wakeref, called only on final release.
+ * @flags: control flags
  *
  * Release our hold on the wakeref. When there are no more users,
  * the runtime pm wakeref will be released after the @fn callback is called
@@ -116,11 +113,25 @@ intel_wakeref_get_if_active(struct intel_wakeref *wf)
  * code otherwise.
  */
 static inline void
-intel_wakeref_put(struct intel_wakeref *wf)
+__intel_wakeref_put(struct intel_wakeref *wf, unsigned long flags)
+#define INTEL_WAKEREF_PUT_ASYNC BIT(0)
 {
 	INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
 	if (unlikely(!atomic_add_unless(&wf->count, -1, 1)))
-		__intel_wakeref_put_last(wf);
+		__intel_wakeref_put_last(wf, flags);
+}
+
+static inline void
+intel_wakeref_put(struct intel_wakeref *wf)
+{
+	might_sleep();
+	__intel_wakeref_put(wf, 0);
+}
+
+static inline void
+intel_wakeref_put_async(struct intel_wakeref *wf)
+{
+	__intel_wakeref_put(wf, INTEL_WAKEREF_PUT_ASYNC);
 }
 
 /**
@@ -185,6 +196,7 @@ intel_wakeref_is_active(const struct intel_wakeref *wf)
 static inline void
 __intel_wakeref_defer_park(struct intel_wakeref *wf)
 {
+	lockdep_assert_held(&wf->mutex);
 	INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count));
 	atomic_set_release(&wf->count, 1);
 }
commit f83d7e3f5189eb78e481cd02da93e4e32a253493
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 18 23:02:46 2019 +0000

    drm/i915: Wait until the intel_wakeref idle callback is complete
    
    When waiting for idle, serialise with any ongoing callback so that it
    will have completed before completing the wait.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191118230254.2615942-12-chris@chris-wilson.co.uk
    (cherry picked from commit f4ba0707c825d60f1d0f5ce7bd3d875e68f3e204)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index 868cc78048d0..ad26d7f4ca3d 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -109,8 +109,17 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 
 int intel_wakeref_wait_for_idle(struct intel_wakeref *wf)
 {
-	return wait_var_event_killable(&wf->wakeref,
-				       !intel_wakeref_is_active(wf));
+	int err;
+
+	might_sleep();
+
+	err = wait_var_event_killable(&wf->wakeref,
+				      !intel_wakeref_is_active(wf));
+	if (err)
+		return err;
+
+	intel_wakeref_unlock_wait(wf);
+	return 0;
 }
 
 static void wakeref_auto_timeout(struct timer_list *t)
diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h
index 5f0c972a80fb..affe4de3746b 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.h
+++ b/drivers/gpu/drm/i915/intel_wakeref.h
@@ -151,6 +151,21 @@ intel_wakeref_unlock(struct intel_wakeref *wf)
 	mutex_unlock(&wf->mutex);
 }
 
+/**
+ * intel_wakeref_unlock_wait: Wait until the active callback is complete
+ * @wf: the wakeref
+ *
+ * Waits for the active callback (under the @wf->mutex or another CPU) is
+ * complete.
+ */
+static inline void
+intel_wakeref_unlock_wait(struct intel_wakeref *wf)
+{
+	mutex_lock(&wf->mutex);
+	mutex_unlock(&wf->mutex);
+	flush_work(&wf->work);
+}
+
 /**
  * intel_wakeref_is_active: Query whether the wakeref is currently held
  * @wf: the wakeref
commit 732f9ca4a737aea3983ad86007e88e7fffe8cd6a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 20 18:22:09 2019 +0000

    drm/i915/gt: Fixup config ifdeffery for pm_suspend_target_state
    
    pm_suspend_target_state is declared under CONFIG_PM_SLEEP but only
    defined under CONFIG_SUSPEND. Play safe and only use the symbol if it is
    both declared and defined.
    
    Reported-by: kbuild-all at lists.01.org
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Fixes: a70a9e998e8e ("drm/i915: Defer rc6 shutdown to suspend_late")
    Cc: Andi Shyti <andi.shyti at intel.com>
    Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191120182209.3967833-1-chris@chris-wilson.co.uk
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index 6187cdd06646..7917cc348375 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -272,7 +272,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
 
 static suspend_state_t pm_suspend_target(void)
 {
-#if IS_ENABLED(CONFIG_PM_SLEEP)
+#if IS_ENABLED(CONFIG_SUSPEND) && IS_ENABLED(CONFIG_PM_SLEEP)
 	return pm_suspend_target_state;
 #else
 	return PM_SUSPEND_TO_IDLE;
commit 03a2a606066cf8af7a090669848e4e84351ded06
Author: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Date:   Fri Nov 22 10:41:15 2019 +0000

    drm/i915/query: Align flavour of engine data lookup
    
    Commit 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for
    engines onto the GT") changed the engine query to iterate over uabi
    engines but left the buffer size calculation look at the physical engine
    count. Difference has no practical consequence but it is nicer to align
    both queries.
    
    Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
    Cc: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191122104115.29610-1-tvrtko.ursulin@linux.intel.com
    (cherry picked from commit 9acc99d8f278e3da398e927774431bd3e947ab2e)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index c27cfef9281c..ef25ce6e395e 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -103,15 +103,18 @@ query_engine_info(struct drm_i915_private *i915,
 	struct drm_i915_engine_info __user *info_ptr;
 	struct drm_i915_query_engine_info query;
 	struct drm_i915_engine_info info = { };
+	unsigned int num_uabi_engines = 0;
 	struct intel_engine_cs *engine;
 	int len, ret;
 
 	if (query_item->flags)
 		return -EINVAL;
 
+	for_each_uabi_engine(engine, i915)
+		num_uabi_engines++;
+
 	len = sizeof(struct drm_i915_query_engine_info) +
-	      RUNTIME_INFO(i915)->num_engines *
-	      sizeof(struct drm_i915_engine_info);
+	      num_uabi_engines * sizeof(struct drm_i915_engine_info);
 
 	ret = copy_query_item(&query, sizeof(query), len, query_item);
 	if (ret != 0)
commit 198dfe671fdfdb79755aa131c191a4cb10a2a8b7
Author: Matt Roper <matthew.d.roper at intel.com>
Date:   Mon Nov 18 10:02:19 2019 -0800

    drm/i915/tgl: Add DKL PHY vswing table for HDMI
    
    The bspec initially provided a single DKL PHY vswing table for both HDMI
    and DP, but was recently updated to include an independent table for
    HDMI.
    
    Bspec: 49292
    Fixes: 978c3e539be2 ("drm/i915/tgl: Add dkl phy programming sequences")
    Cc: Clinton A Taylor <clinton.a.taylor at intel.com>
    Cc: Lucas De Marchi <lucas.demarchi at intel.com>
    Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191118180219.9309-1-matthew.d.roper@intel.com
    Reviewed-by: José Roberto de Souza <jose.souza at intel.com>
    (cherry picked from commit 362bfb995b78394aefe61f7cc0511ef7c50bb11e)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0d6e494b4508..c7c2b349858d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -593,7 +593,7 @@ struct tgl_dkl_phy_ddi_buf_trans {
 	u32 dkl_de_emphasis_control;
 };
 
-static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_ddi_translations[] = {
+static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_dp_ddi_trans[] = {
 				/* VS	pre-emp	Non-trans mV	Pre-emph dB */
 	{ 0x7, 0x0, 0x00 },	/* 0	0	400mV		0 dB */
 	{ 0x5, 0x0, 0x03 },	/* 0	1	400mV		3.5 dB */
@@ -607,6 +607,20 @@ static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_ddi_translations[] = {
 	{ 0x0, 0x0, 0x00 },	/* 3	0	1200mV		0 dB HDMI default */
 };
 
+static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_hdmi_ddi_trans[] = {
+				/* HDMI Preset	VS	Pre-emph */
+	{ 0x7, 0x0, 0x0 },	/* 1		400mV	0dB */
+	{ 0x6, 0x0, 0x0 },	/* 2		500mV	0dB */
+	{ 0x4, 0x0, 0x0 },	/* 3		650mV	0dB */
+	{ 0x2, 0x0, 0x0 },	/* 4		800mV	0dB */
+	{ 0x0, 0x0, 0x0 },	/* 5		1000mV	0dB */
+	{ 0x0, 0x0, 0x5 },	/* 6		Full	-1.5 dB */
+	{ 0x0, 0x0, 0x6 },	/* 7		Full	-1.8 dB */
+	{ 0x0, 0x0, 0x7 },	/* 8		Full	-2 dB */
+	{ 0x0, 0x0, 0x8 },	/* 9		Full	-2.5 dB */
+	{ 0x0, 0x0, 0xA },	/* 10		Full	-3 dB */
+};
+
 static const struct ddi_buf_trans *
 bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 {
@@ -898,7 +912,7 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por
 			icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
 						0, &n_entries);
 		else
-			n_entries = ARRAY_SIZE(tgl_dkl_phy_ddi_translations);
+			n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
 		default_entry = n_entries - 1;
 	} else if (INTEL_GEN(dev_priv) == 11) {
 		if (intel_phy_is_combo(dev_priv, phy))
@@ -2371,7 +2385,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
 			icl_get_combo_buf_trans(dev_priv, encoder->type,
 						intel_dp->link_rate, &n_entries);
 		else
-			n_entries = ARRAY_SIZE(tgl_dkl_phy_ddi_translations);
+			n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
 	} else if (INTEL_GEN(dev_priv) == 11) {
 		if (intel_phy_is_combo(dev_priv, phy))
 			icl_get_combo_buf_trans(dev_priv, encoder->type,
@@ -2823,8 +2837,13 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
 	const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
 	u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
 
-	n_entries = ARRAY_SIZE(tgl_dkl_phy_ddi_translations);
-	ddi_translations = tgl_dkl_phy_ddi_translations;
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
+		ddi_translations = tgl_dkl_phy_hdmi_ddi_trans;
+	} else {
+		n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
+		ddi_translations = tgl_dkl_phy_dp_ddi_trans;
+	}
 
 	if (level >= n_entries)
 		level = n_entries - 1;
commit d74a7566bef76b44416071fbb7e34f301eac8d98
Author: Matt Roper <matthew.d.roper at intel.com>
Date:   Mon Nov 18 08:44:12 2019 -0800

    drm/i915/ehl: Update voltage level checks
    
    The bspec was recently updated with new cdclk -> voltage level tables to
    accommodate the new 324/326.4 cdclk values.
    
    Bspec: 21809
    Fixes: 63c9dae71dc5 ("drm/i915/ehl: Add voltage level requirement table")
    Cc: José Roberto de Souza <jose.souza at intel.com>
    Cc: Vivek Kasireddy <vivek.kasireddy at intel.com>
    Cc: Bob Paauwe <bob.j.paauwe at intel.com>
    Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191118164412.26216-1-matthew.d.roper@intel.com
    Reviewed-by: José Roberto de Souza <jose.souza at intel.com>
    (cherry picked from commit d147483884ed08ee6bb618ef610ee0329a27fda7)
    Signed-off-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 0caef2592a7e..ed8c7ce62119 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1273,7 +1273,9 @@ static u8 icl_calc_voltage_level(int cdclk)
 
 static u8 ehl_calc_voltage_level(int cdclk)
 {
-	if (cdclk > 312000)
+	if (cdclk > 326400)
+		return 3;
+	else if (cdclk > 312000)
 		return 2;
 	else if (cdclk > 180000)
 		return 1;
commit e20c9284c8f212081afc28471daaac9b0d54252f
Author: AngeloGioacchino Del Regno <kholk11 at gmail.com>
Date:   Thu Oct 31 11:44:02 2019 +0100

    drm/msm/adreno: Add support for Adreno 510 GPU
    
    The Adreno 510 GPU is a stripped version of the Adreno 5xx,
    found in low-end SoCs like 8x56 and 8x76, which has 256K of
    GMEM, with no GPMU nor ZAP.
    Also, since the Adreno 5xx part of this driver seems to be
    developed with high-end Adreno GPUs in mind, and since this
    is a lower end one, add a comment making clear which GPUs
    which support is not implemented yet is not using the GPMU
    related hw init code, so that future developers will not go
    crazy with that.
    
    By the way, the lower end Adreno GPUs with no GPMU are:
    A505/A506/A510 (usually no ZAP firmware)
    A508/A509/A512 (usually with ZAP firmware)
    
    Signed-off-by: AngeloGioacchino Del Regno <kholk11 at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 7fdc9e2bcaac..b02e2042547f 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -353,6 +353,9 @@ static int a5xx_me_init(struct msm_gpu *gpu)
 		 * 2D mode 3 draw
 		 */
 		OUT_RING(ring, 0x0000000B);
+	} else if (adreno_is_a510(adreno_gpu)) {
+		/* Workaround for token and syncs */
+		OUT_RING(ring, 0x00000001);
 	} else {
 		/* No workarounds enabled */
 		OUT_RING(ring, 0x00000000);
@@ -568,15 +571,24 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 		0x00100000 + adreno_gpu->gmem - 1);
 	gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
 
-	gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
-	if (adreno_is_a530(adreno_gpu))
-		gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
-	if (adreno_is_a540(adreno_gpu))
-		gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
-	gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
-	gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
-
-	gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22));
+	if (adreno_is_a510(adreno_gpu)) {
+		gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x20);
+		gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A);
+		gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+			  (0x200 << 11 | 0x200 << 22));
+	} else {
+		gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
+		if (adreno_is_a530(adreno_gpu))
+			gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
+		if (adreno_is_a540(adreno_gpu))
+			gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
+		gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+			  (0x400 << 11 | 0x300 << 22));
+	}
 
 	if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
 		gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));
@@ -589,6 +601,19 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 	/* Enable ME/PFP split notification */
 	gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
 
+	/*
+	 *  In A5x, CCU can send context_done event of a particular context to
+	 *  UCHE which ultimately reaches CP even when there is valid
+	 *  transaction of that context inside CCU. This can let CP to program
+	 *  config registers, which will make the "valid transaction" inside
+	 *  CCU to be interpreted differently. This can cause gpu fault. This
+	 *  bug is fixed in latest A510 revision. To enable this bug fix -
+	 *  bit[11] of RB_DBG_ECO_CNTL need to be set to 0, default is 1
+	 *  (disable). For older A510 version this bit is unused.
+	 */
+	if (adreno_is_a510(adreno_gpu))
+		gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, (1 << 11), 0);
+
 	/* Enable HWCG */
 	a5xx_set_hwcg(gpu, true);
 
@@ -635,7 +660,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 	/* UCHE */
 	gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16));
 
-	if (adreno_is_a530(adreno_gpu))
+	if (adreno_is_a530(adreno_gpu) || adreno_is_a510(adreno_gpu))
 		gpu_write(gpu, REG_A5XX_CP_PROTECT(17),
 			ADRENO_PROTECT_RW(0x10000, 0x8000));
 
@@ -679,7 +704,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 
 	a5xx_preempt_hw_init(gpu);
 
-	a5xx_gpmu_ucode_init(gpu);
+	if (!adreno_is_a510(adreno_gpu))
+		a5xx_gpmu_ucode_init(gpu);
 
 	ret = a5xx_ucode_init(gpu);
 	if (ret)
@@ -712,7 +738,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 	}
 
 	/*
-	 * Try to load a zap shader into the secure world. If successful
+	 * If the chip that we are using does support loading one, then
+	 * try to load a zap shader into the secure world. If successful
 	 * we can use the CP to switch out of secure mode. If not then we
 	 * have no resource but to try to switch ourselves out manually. If we
 	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
@@ -1066,6 +1093,7 @@ static void a5xx_dump(struct msm_gpu *gpu)
 
 static int a5xx_pm_resume(struct msm_gpu *gpu)
 {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	int ret;
 
 	/* Turn on the core power */
@@ -1073,6 +1101,15 @@ static int a5xx_pm_resume(struct msm_gpu *gpu)
 	if (ret)
 		return ret;
 
+	if (adreno_is_a510(adreno_gpu)) {
+		/* Halt the sp_input_clk at HM level */
+		gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0x00000055);
+		a5xx_set_hwcg(gpu, true);
+		/* Turn on sp_input_clk at HM level */
+		gpu_rmw(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xff, 0);
+		return 0;
+	}
+
 	/* Turn the RBCCU domain first to limit the chances of voltage droop */
 	gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000);
 
@@ -1101,9 +1138,17 @@ static int a5xx_pm_resume(struct msm_gpu *gpu)
 
 static int a5xx_pm_suspend(struct msm_gpu *gpu)
 {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	u32 mask = 0xf;
+
+	/* A510 has 3 XIN ports in VBIF */
+	if (adreno_is_a510(adreno_gpu))
+		mask = 0x7;
+
 	/* Clear the VBIF pipe before shutting down */
-	gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF);
-	spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) == 0xF);
+	gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, mask);
+	spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) &
+				mask) == mask);
 
 	gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0);
 
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c
index a3a06db675ba..321a8061fd32 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_power.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c
@@ -297,6 +297,10 @@ int a5xx_power_init(struct msm_gpu *gpu)
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	int ret;
 
+	/* Not all A5xx chips have a GPMU */
+	if (adreno_is_a510(adreno_gpu))
+		return 0;
+
 	/* Set up the limits management */
 	if (adreno_is_a530(adreno_gpu))
 		a530_lm_setup(gpu);
@@ -326,6 +330,9 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
 	unsigned int *data, *ptr, *cmds;
 	unsigned int cmds_size;
 
+	if (adreno_is_a510(adreno_gpu))
+		return;
+
 	if (a5xx_gpu->gpmu_bo)
 		return;
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 0888e0df660d..fbbdf86504f5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -114,6 +114,21 @@ static const struct adreno_info gpulist[] = {
 		.gmem  = (SZ_1M + SZ_512K),
 		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
 		.init  = a4xx_gpu_init,
+	}, {
+		.rev   = ADRENO_REV(5, 1, 0, ANY_ID),
+		.revn = 510,
+		.name = "A510",
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = SZ_256K,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.init = a5xx_gpu_init,
 	}, {
 		.rev = ADRENO_REV(5, 3, 0, 2),
 		.revn = 530,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index d225a8a92e58..e71a7570ef72 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -212,6 +212,11 @@ static inline int adreno_is_a430(struct adreno_gpu *gpu)
        return gpu->revn == 430;
 }
 
+static inline int adreno_is_a510(struct adreno_gpu *gpu)
+{
+	return gpu->revn == 510;
+}
+
 static inline int adreno_is_a530(struct adreno_gpu *gpu)
 {
 	return gpu->revn == 530;
commit 3f3c8aff1f8f735b94d9f342be6f14de062b4c66
Author: AngeloGioacchino Del Regno <kholk11 at gmail.com>
Date:   Thu Oct 31 11:44:01 2019 +0100

    drm/msm/dsi: Add configuration for 8x76
    
    MSM8976, MSM8976 and APQ variants have DSI version 3:10040002
    (DSI 6G V1.4.2), featuring two DSIs.
    They need three clocks (mdp_core, iface, bus), one GDSC and
    two vregs, VDDA at 1.2V and VDDIO at 1.8V.
    
    Signed-off-by: AngeloGioacchino Del Regno <kholk11 at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index e74dc8cc904b..86ad3fdf207d 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -66,6 +66,26 @@ static const struct msm_dsi_config msm8916_dsi_cfg = {
 	.num_dsi = 1,
 };
 
+static const char * const dsi_8976_bus_clk_names[] = {
+	"mdp_core", "iface", "bus",
+};
+
+static const struct msm_dsi_config msm8976_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.reg_cfg = {
+		.num = 3,
+		.regs = {
+			{"gdsc", -1, -1},
+			{"vdda", 100000, 100},	/* 1.2 V */
+			{"vddio", 100000, 100},	/* 1.8 V */
+		},
+	},
+	.bus_clk_names = dsi_8976_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_8976_bus_clk_names),
+	.io_start = { 0x1a94000, 0x1a96000 },
+	.num_dsi = 2,
+};
+
 static const struct msm_dsi_config msm8994_dsi_cfg = {
 	.io_offset = DSI_6G_REG_SHIFT,
 	.reg_cfg = {
@@ -197,6 +217,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
 		&msm8916_dsi_cfg, &msm_dsi_6g_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
 		&msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_2,
+		&msm8976_dsi_cfg, &msm_dsi_6g_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_0,
 		&msm8998_dsi_cfg, &msm_dsi_6g_v2_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index e2b7a7dfbe49..50a37ceb6a25 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -17,6 +17,7 @@
 #define MSM_DSI_6G_VER_MINOR_V1_3	0x10030000
 #define MSM_DSI_6G_VER_MINOR_V1_3_1	0x10030001
 #define MSM_DSI_6G_VER_MINOR_V1_4_1	0x10040001
+#define MSM_DSI_6G_VER_MINOR_V1_4_2	0x10040002
 #define MSM_DSI_6G_VER_MINOR_V2_2_0	0x20000000
 #define MSM_DSI_6G_VER_MINOR_V2_2_1	0x20020001
 
commit 332d6084d4f7e34f607c9159e3532a9ca27d8d46
Author: AngeloGioacchino Del Regno <kholk11 at gmail.com>
Date:   Thu Oct 31 11:43:59 2019 +0100

    drm/msm/dsi: Add configuration for 28nm PLL on family B
    
    The 28nm PLL has a different iospace on MSM/APQ family B SoCs:
    add a new configuration and use it when the DT reports the
    "qcom,dsi-phy-28nm-hpm-fam-b" compatible.
    
    Signed-off-by: AngeloGioacchino Del Regno <kholk11 at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index aa22c3ae5230..b0cfa67d2a57 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -483,6 +483,8 @@ static const struct of_device_id dsi_phy_dt_match[] = {
 #ifdef CONFIG_DRM_MSM_DSI_28NM_PHY
 	{ .compatible = "qcom,dsi-phy-28nm-hpm",
 	  .data = &dsi_phy_28nm_hpm_cfgs },
+	{ .compatible = "qcom,dsi-phy-28nm-hpm-fam-b",
+	  .data = &dsi_phy_28nm_hpm_famb_cfgs },
 	{ .compatible = "qcom,dsi-phy-28nm-lp",
 	  .data = &dsi_phy_28nm_lp_cfgs },
 #endif
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
index c4069ce6afe6..24b294ed3059 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
@@ -40,6 +40,7 @@ struct msm_dsi_phy_cfg {
 };
 
 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
index b384ea20f359..c3c580cfd8b1 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
@@ -168,6 +168,24 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
 	.num_dsi_phy = 2,
 };
 
+const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = {
+	.type = MSM_DSI_PHY_28NM_HPM,
+	.src_pll_truthtable = { {true, true}, {false, true} },
+	.reg_cfg = {
+		.num = 1,
+		.regs = {
+			{"vddio", 100000, 100},
+		},
+	},
+	.ops = {
+		.enable = dsi_28nm_phy_enable,
+		.disable = dsi_28nm_phy_disable,
+		.init = msm_dsi_phy_init_common,
+	},
+	.io_start = { 0x1a94400, 0x1a96400 },
+	.num_dsi_phy = 2,
+};
+
 const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
 	.type = MSM_DSI_PHY_28NM_LP,
 	.src_pll_truthtable = { {true, true}, {true, true} },
commit 1860f2a8b8b1c7007a175b207b0805d94a11caea
Author: AngeloGioacchino Del Regno <kholk11 at gmail.com>
Date:   Thu Oct 31 11:43:58 2019 +0100

    drm/msm/mdp5: Add configuration for msm8x76
    
    Add the configuration entries for the MDP5 v1.11, found on
    MSM8956, MSM8976 and APQ variants.
    
    Signed-off-by: AngeloGioacchino Del Regno <kholk11 at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index 7c9c1ddae821..1f48f64539a2 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -545,6 +545,103 @@ static const struct mdp5_cfg_hw msm8x96_config = {
 	.max_clk = 412500000,
 };
 
+const struct mdp5_cfg_hw msm8x76_config = {
+	.name = "msm8x76",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			MDP_CAP_DSC |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.ctl = {
+		.count = 3,
+		.base = { 0x01000, 0x01200, 0x01400 },
+		.flush_hw_mask = 0xffffffff,
+	},
+	.smp = {
+		.mmb_count = 10,
+		.mmb_size = 10240,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_VIG1] = 9,
+			[SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.pipe_vig = {
+		.count = 2,
+		.base = { 0x04000, 0x06000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x440DC },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+	.lm = {
+		.count = 2,
+		.base = { 0x44000, 0x45000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 8,
+		.max_width = 2560,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+
+	},
+	.pp = {
+		.count = 3,
+		.base = { 0x70000, 0x70800, 0x72000 },
+	},
+	.dsc = {
+		.count = 2,
+		.base = { 0x80000, 0x80400 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+		},
+	},
+	.max_clk = 360000000,
+};
+
 static const struct mdp5_cfg_hw msm8917_config = {
 	.name = "msm8917",
 	.mdp = {
@@ -745,6 +842,7 @@ static const struct mdp5_cfg_handler cfg_handlers_v1[] = {
 	{ .revision = 6, .config = { .hw = &msm8x16_config } },
 	{ .revision = 9, .config = { .hw = &msm8x94_config } },
 	{ .revision = 7, .config = { .hw = &msm8x96_config } },
+	{ .revision = 11, .config = { .hw = &msm8x76_config } },
 	{ .revision = 15, .config = { .hw = &msm8917_config } },
 };
 
commit 2ab45a0973a86bfffaf2f0c49f49119ba5a6f4af
Author: AngeloGioacchino Del Regno <kholk11 at gmail.com>
Date:   Thu Oct 31 11:43:57 2019 +0100

    dt-bindings: msm/mdp5: Document optional TBU and TBU_RT clocks
    
    These two clocks aren't present in all versions of the MDP5 HW:
    where present, they are needed to enable the Translation Buffer
    Unit(s).
    
    Signed-off-by: AngeloGioacchino Del Regno <kholk11 at gmail.com>
    Acked-by: Rob Herring <robh at kernel.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt b/Documentation/devicetree/bindings/display/msm/mdp5.txt
index 4e11338548aa..43d11279c925 100644
--- a/Documentation/devicetree/bindings/display/msm/mdp5.txt
+++ b/Documentation/devicetree/bindings/display/msm/mdp5.txt
@@ -76,6 +76,8 @@ Required properties:
 Optional properties:
 - clock-names: the following clocks are optional:
   * "lut"
+  * "tbu"
+  * "tbu_rt"
 
 Example:
 
commit 1c2a9f254c26fa9a3e96a922214873880d5333a3
Author: AngeloGioacchino Del Regno <kholk11 at gmail.com>
Date:   Thu Oct 31 11:43:56 2019 +0100

    drm/msm/mdp5: Add optional TBU and TBU_RT clocks
    
    Some SoCs, like MSM8956/8976 (and APQ variants), do feature these
    clocks and we need to enable them in order to get both of the
    hw (mdp5/rot) Translation Buffer Units (TBUs) to properly work.
    
    Signed-off-by: AngeloGioacchino Del Regno <kholk11 at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 5476892a335f..e43ecd4be10a 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -309,6 +309,10 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
 	mdp5_kms->enable_count--;
 	WARN_ON(mdp5_kms->enable_count < 0);
 
+	if (mdp5_kms->tbu_rt_clk)
+		clk_disable_unprepare(mdp5_kms->tbu_rt_clk);
+	if (mdp5_kms->tbu_clk)
+		clk_disable_unprepare(mdp5_kms->tbu_clk);
 	clk_disable_unprepare(mdp5_kms->ahb_clk);
 	clk_disable_unprepare(mdp5_kms->axi_clk);
 	clk_disable_unprepare(mdp5_kms->core_clk);
@@ -329,6 +333,10 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
 	clk_prepare_enable(mdp5_kms->core_clk);
 	if (mdp5_kms->lut_clk)
 		clk_prepare_enable(mdp5_kms->lut_clk);
+	if (mdp5_kms->tbu_clk)
+		clk_prepare_enable(mdp5_kms->tbu_clk);
+	if (mdp5_kms->tbu_rt_clk)
+		clk_prepare_enable(mdp5_kms->tbu_rt_clk);
 
 	return 0;
 }
@@ -965,6 +973,8 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 
 	/* optional clocks: */
 	get_clk(pdev, &mdp5_kms->lut_clk, "lut", false);
+	get_clk(pdev, &mdp5_kms->tbu_clk, "tbu", false);
+	get_clk(pdev, &mdp5_kms->tbu_rt_clk, "tbu_rt", false);
 
 	/* we need to set a default rate before enabling.  Set a safe
 	 * rate first, then figure out hw revision, and then set a
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
index d1bf4fdfc815..128866742593 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
@@ -53,6 +53,8 @@ struct mdp5_kms {
 	struct clk *ahb_clk;
 	struct clk *core_clk;
 	struct clk *lut_clk;
+	struct clk *tbu_clk;
+	struct clk *tbu_rt_clk;
 	struct clk *vsync_clk;
 
 	/*
commit abdfd18fe07373981c5375a79a76703add0db0f0
Author: Rob Clark <robdclark at chromium.org>
Date:   Mon Oct 7 13:31:08 2019 -0700

    drm/msm: always dump buffer base/size
    
    Even if we are not dumping the buffer's contents, it is useful to log
    their base address and size.  This makes it easier to see when different
    gpu pointers point to a single buffer, for example higher mipmap levels
    of a single texture.
    
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c
index 39a5832fbfd1..af7ceb246c7c 100644
--- a/drivers/gpu/drm/msm/msm_rd.c
+++ b/drivers/gpu/drm/msm/msm_rd.c
@@ -298,7 +298,7 @@ void msm_rd_debugfs_cleanup(struct msm_drm_private *priv)
 
 static void snapshot_buf(struct msm_rd_state *rd,
 		struct msm_gem_submit *submit, int idx,
-		uint64_t iova, uint32_t size)
+		uint64_t iova, uint32_t size, bool full)
 {
 	struct msm_gem_object *obj = submit->bos[idx].obj;
 	unsigned offset = 0;
@@ -318,6 +318,9 @@ static void snapshot_buf(struct msm_rd_state *rd,
 	rd_write_section(rd, RD_GPUADDR,
 			(uint32_t[3]){ iova, size, iova >> 32 }, 12);
 
+	if (!full)
+		return;
+
 	/* But only dump the contents of buffers marked READ */
 	if (!(submit->bos[idx].flags & MSM_SUBMIT_BO_READ))
 		return;
@@ -381,8 +384,7 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
 	rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4));
 
 	for (i = 0; i < submit->nr_bos; i++)
-		if (should_dump(submit, i))
-			snapshot_buf(rd, submit, i, 0, 0);
+		snapshot_buf(rd, submit, i, 0, 0, should_dump(submit, i));
 
 	for (i = 0; i < submit->nr_cmds; i++) {
 		uint32_t szd  = submit->cmd[i].size; /* in dwords */
@@ -390,7 +392,7 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
 		/* snapshot cmdstream bo's (if we haven't already): */
 		if (!should_dump(submit, i)) {
 			snapshot_buf(rd, submit, submit->cmd[i].idx,
-					submit->cmd[i].iova, szd * 4);
+					submit->cmd[i].iova, szd * 4, true);
 		}
 	}
 
commit c4b0222e628f5b56af149d1a926170b2e9a16220
Author: Rob Clark <robdclark at chromium.org>
Date:   Mon Oct 7 13:31:07 2019 -0700

    drm/msm: fix rd dumping for split-IB1
    
    When IB1 is split into multiple cmd buffers, we'd emit multiple
    RD_CMDSTREAM_ADDR per submit.  But after this packet is handled
    by the cffdump parser, it resets it's known buffers on the next
    GPUADDR packet, so subsequent RD_CMDSTREAM_ADDR packets from the
    same submit would not find their buffers.
    
    Re-work the loop to snapshot all buffers before RD_CMDSTREAM_ADDR
    to avoid this problem.
    
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c
index c7832a951039..39a5832fbfd1 100644
--- a/drivers/gpu/drm/msm/msm_rd.c
+++ b/drivers/gpu/drm/msm/msm_rd.c
@@ -385,7 +385,6 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
 			snapshot_buf(rd, submit, i, 0, 0);
 
 	for (i = 0; i < submit->nr_cmds; i++) {
-		uint64_t iova = submit->cmd[i].iova;
 		uint32_t szd  = submit->cmd[i].size; /* in dwords */
 
 		/* snapshot cmdstream bo's (if we haven't already): */
@@ -393,6 +392,11 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
 			snapshot_buf(rd, submit, submit->cmd[i].idx,
 					submit->cmd[i].iova, szd * 4);
 		}
+	}
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		uint64_t iova = submit->cmd[i].iova;
+		uint32_t szd  = submit->cmd[i].size; /* in dwords */
 
 		switch (submit->cmd[i].type) {
 		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
commit fd6c798b58e0d6adaf336a0ddc91f127ff82a75d
Author: Brian Masney <masneyb at onstation.org>
Date:   Wed Aug 14 20:48:51 2019 -0400

    drm/msm/hdmi: silence -EPROBE_DEFER warning
    
    Silence a warning message due to an -EPROBE_DEFER error to help cleanup
    the system boot log.
    
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
index 1697e61f9c2f..8a38d4b95102 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
@@ -29,8 +29,12 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy)
 		reg = devm_regulator_get(dev, cfg->reg_names[i]);
 		if (IS_ERR(reg)) {
 			ret = PTR_ERR(reg);
-			DRM_DEV_ERROR(dev, "failed to get phy regulator: %s (%d)\n",
-				cfg->reg_names[i], ret);
+			if (ret != -EPROBE_DEFER) {
+				DRM_DEV_ERROR(dev,
+					      "failed to get phy regulator: %s (%d)\n",
+					      cfg->reg_names[i], ret);
+			}
+
 			return ret;
 		}
 
commit 49c4868ab01cbe9bf06e23d5d65c8afea97ecf3f
Author: Stephan Gerhold <stephan at gerhold.net>
Date:   Wed Oct 23 18:56:17 2019 +0200

    drm/msm/dsi: Implement qcom, dsi-phy-regulator-ldo-mode for 28nm PHY
    
    The DSI PHY regulator supports two regulator modes: LDO and DCDC.
    This mode can be selected using the "qcom,dsi-phy-regulator-ldo-mode"
    device tree property.
    
    However, at the moment only the 20nm PHY driver actually implements
    that option. Add a check in the 28nm PHY driver to program the
    registers correctly for LDO mode.
    
    Tested-by: Nikita Travkin <nikitos.tr at gmail.com> # l8150
    Signed-off-by: Stephan Gerhold <stephan at gerhold.net>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191023165617.28738-1-stephan@gerhold.net

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
index b3f678f6c2aa..b384ea20f359 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
@@ -39,15 +39,10 @@ static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
 		DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
 }
 
-static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
+static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy)
 {
 	void __iomem *base = phy->reg_base;
 
-	if (!enable) {
-		dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
-		return;
-	}
-
 	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
 	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
 	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
@@ -56,6 +51,39 @@ static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
 	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
 	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
 	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
+	dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
+}
+
+static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->reg_base;
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0x7);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
+
+	if (phy->cfg->type == MSM_DSI_PHY_28NM_LP)
+		dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x05);
+	else
+		dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x0d);
+}
+
+static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
+{
+	if (!enable) {
+		dsi_phy_write(phy->reg_base +
+			      REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+		return;
+	}
+
+	if (phy->regulator_ldo_mode)
+		dsi_28nm_phy_regulator_enable_ldo(phy);
+	else
+		dsi_28nm_phy_regulator_enable_dcdc(phy);
 }
 
 static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
@@ -77,8 +105,6 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
 
 	dsi_28nm_phy_regulator_ctrl(phy, true);
 
-	dsi_phy_write(base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
-
 	dsi_28nm_dphy_set_timing(phy, timing);
 
 	dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
commit 8856c5064834a2600fbe99d4b6de041e6a40621a
Author: Ben Dooks <ben.dooks at codethink.co.uk>
Date:   Wed Oct 9 13:05:22 2019 +0100

    drm/msm/mdp5: make config variables static
    
    A number of the config structs are not exported so make
    them static to avoid the following sparse warnings:
    
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:17:26: warning: symbol 'msm8x74v1_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:101:26: warning: symbol 'msm8x74v2_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:183:26: warning: symbol 'apq8084_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:278:26: warning: symbol 'msm8x16_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:345:26: warning: symbol 'msm8x94_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:440:26: warning: symbol 'msm8x96_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:548:26: warning: symbol 'msm8917_config' was not declared. Should it be static?
    drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c:633:26: warning: symbol 'msm8998_config' was not declared. Should it be static?
    
    Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191009120522.17019-1-ben.dooks@codethink.co.uk
    Link: https://patchwork.freedesktop.org/patch/msgid/20190918195722.2149227-1-arnd@arndb.de

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index f6e71ff539ca..7c9c1ddae821 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -14,7 +14,7 @@ struct mdp5_cfg_handler {
 /* mdp5_cfg must be exposed (used in mdp5.xml.h) */
 const struct mdp5_cfg_hw *mdp5_cfg = NULL;
 
-const struct mdp5_cfg_hw msm8x74v1_config = {
+static const struct mdp5_cfg_hw msm8x74v1_config = {
 	.name = "msm8x74v1",
 	.mdp = {
 		.count = 1,
@@ -98,7 +98,7 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
 	.max_clk = 200000000,
 };
 
-const struct mdp5_cfg_hw msm8x74v2_config = {
+static const struct mdp5_cfg_hw msm8x74v2_config = {
 	.name = "msm8x74",
 	.mdp = {
 		.count = 1,
@@ -180,7 +180,7 @@ const struct mdp5_cfg_hw msm8x74v2_config = {
 	.max_clk = 200000000,
 };
 
-const struct mdp5_cfg_hw apq8084_config = {
+static const struct mdp5_cfg_hw apq8084_config = {
 	.name = "apq8084",
 	.mdp = {
 		.count = 1,
@@ -275,7 +275,7 @@ const struct mdp5_cfg_hw apq8084_config = {
 	.max_clk = 320000000,
 };
 
-const struct mdp5_cfg_hw msm8x16_config = {
+static const struct mdp5_cfg_hw msm8x16_config = {
 	.name = "msm8x16",
 	.mdp = {
 		.count = 1,
@@ -342,7 +342,7 @@ const struct mdp5_cfg_hw msm8x16_config = {
 	.max_clk = 320000000,
 };
 
-const struct mdp5_cfg_hw msm8x94_config = {
+static const struct mdp5_cfg_hw msm8x94_config = {
 	.name = "msm8x94",
 	.mdp = {
 		.count = 1,
@@ -437,7 +437,7 @@ const struct mdp5_cfg_hw msm8x94_config = {
 	.max_clk = 400000000,
 };
 
-const struct mdp5_cfg_hw msm8x96_config = {
+static const struct mdp5_cfg_hw msm8x96_config = {
 	.name = "msm8x96",
 	.mdp = {
 		.count = 1,
@@ -545,7 +545,7 @@ const struct mdp5_cfg_hw msm8x96_config = {
 	.max_clk = 412500000,
 };
 
-const struct mdp5_cfg_hw msm8917_config = {
+static const struct mdp5_cfg_hw msm8917_config = {
 	.name = "msm8917",
 	.mdp = {
 		.count = 1,
@@ -630,7 +630,7 @@ const struct mdp5_cfg_hw msm8917_config = {
 	.max_clk = 320000000,
 };
 
-const struct mdp5_cfg_hw msm8998_config = {
+static const struct mdp5_cfg_hw msm8998_config = {
 	.name = "msm8998",
 	.mdp = {
 		.count = 1,
commit fcb5c172409da337f81a84fb5dc8c6baa4e8dc67
Author: Ben Dooks <ben.dooks at codethink.co.uk>
Date:   Wed Oct 9 12:46:07 2019 +0100

    drm/msm: make a5xx_show and a5xx_gpu_state_put static
    
    The a5xx_show and a5xx_gpu_state_put objects are not exported
    outside of the file, so make them static to avoid the following
    warnings from sparse:
    
    drivers/gpu/drm/msm/adreno/a5xx_gpu.c:1292:5: warning: symbol 'a5xx_gpu_state_put' was not declared. Should it be static?
    drivers/gpu/drm/msm/adreno/a5xx_gpu.c:1302:6: warning: symbol 'a5xx_show' was not declared. Should it be static?
    
    Reviewed-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191009114607.701-1-ben.dooks@codethink.co.uk

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index e9c55d1d6c04..7fdc9e2bcaac 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1289,7 +1289,7 @@ static void a5xx_gpu_state_destroy(struct kref *kref)
 	kfree(a5xx_state);
 }
 
-int a5xx_gpu_state_put(struct msm_gpu_state *state)
+static int a5xx_gpu_state_put(struct msm_gpu_state *state)
 {
 	if (IS_ERR_OR_NULL(state))
 		return 1;
@@ -1299,8 +1299,8 @@ int a5xx_gpu_state_put(struct msm_gpu_state *state)
 
 
 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
-void a5xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
-		struct drm_printer *p)
+static void a5xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		      struct drm_printer *p)
 {
 	int i, j;
 	u32 pos = 0;
commit df4954e30d0e6786b95c228f931a52261ce6b8d5
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Wed Oct 9 22:13:23 2019 +0800

    drm/msm/mdp5: Remove set but not used variable 'hw_cfg' in modeset_init
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c: In function modeset_init:
    drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c:458:28: warning: variable hw_cfg set but not used [-Wunused-but-set-variable]
    
    It is not used since commit 36d1364abbed ("drm/msm/mdp5:
    Clean up interface assignment")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/1570630403-92371-1-git-send-email-zhengbin13@huawei.com

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index f8bd0bfcf4b0..5476892a335f 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -461,14 +461,11 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
 {
 	struct drm_device *dev = mdp5_kms->dev;
 	struct msm_drm_private *priv = dev->dev_private;
-	const struct mdp5_cfg_hw *hw_cfg;
 	unsigned int num_crtcs;
 	int i, ret, pi = 0, ci = 0;
 	struct drm_plane *primary[MAX_BASES] = { NULL };
 	struct drm_plane *cursor[MAX_BASES] = { NULL };
 
-	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
-
 	/*
 	 * Construct encoders and modeset initialize connector devices
 	 * for each external display interface.
commit 2e3cc607af53cde972e04bae3ff9cbb0d82b1dc7
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Thu Oct 10 14:55:06 2019 +0800

    drm/msm/dsi: Remove set but not used variable 'lp'
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/dsi/dsi_host.c: In function dsi_cmd_dma_rx:
    drivers/gpu/drm/msm/dsi/dsi_host.c:1302:7: warning: variable lp set but not used [-Wunused-but-set-variable]
    
    It is not used since commit a689554ba6ed ("drm/msm:
    Initial add DSI connector support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/1570690506-83287-5-git-send-email-zhengbin13@huawei.com

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 663ff9f4fac9..4851188f11ba 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1291,14 +1291,13 @@ static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
 static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host,
 			u8 *buf, int rx_byte, int pkt_size)
 {
-	u32 *lp, *temp, data;
+	u32 *temp, data;
 	int i, j = 0, cnt;
 	u32 read_cnt;
 	u8 reg[16];
 	int repeated_bytes = 0;
 	int buf_offset = buf - msm_host->rx_buf;
 
-	lp = (u32 *)buf;
 	temp = (u32 *)reg;
 	cnt = (rx_byte + 3) >> 2;
 	if (cnt > 4)
commit 7264af3ed8d409eadc1dc878879594b0b3b5e79b
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Thu Oct 10 14:55:05 2019 +0800

    drm/msm/dsi: Remove set but not used variable 'lpx'
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/dsi/phy/dsi_phy.c: In function msm_dsi_dphy_timing_calc_v2:
    drivers/gpu/drm/msm/dsi/phy/dsi_phy.c:156:17: warning: variable lpx set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/dsi/phy/dsi_phy.c: In function msm_dsi_dphy_timing_calc_v3:
    drivers/gpu/drm/msm/dsi/phy/dsi_phy.c:273:17: warning: variable lpx set but not used [-Wunused-but-set-variable]
    
    'lpx' in msm_dsi_dphy_timing_calc_v2 is not used since commit a4df68fa232e
    ("drm/msm/dsi: Add new method to calculate 14nm PHY timings")
    
    'lpx' in msm_dsi_dphy_timing_calc_v3 is not used since commit f1fa7ff44056
    ("drm/msm/dsi: implement auto PHY timing calculator for 10nm PHY")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/1570690506-83287-4-git-send-email-zhengbin13@huawei.com

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 3522863a4984..aa22c3ae5230 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -145,7 +145,7 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
 {
 	const unsigned long bit_rate = clk_req->bitclk_rate;
 	const unsigned long esc_rate = clk_req->escclk_rate;
-	s32 ui, ui_x8, lpx;
+	s32 ui, ui_x8;
 	s32 tmax, tmin;
 	s32 pcnt0 = 50;
 	s32 pcnt1 = 50;
@@ -175,7 +175,6 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
 
 	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
 	ui_x8 = ui << 3;
-	lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
 
 	temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8);
 	tmin = max_t(s32, temp, 0);
@@ -262,7 +261,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
 {
 	const unsigned long bit_rate = clk_req->bitclk_rate;
 	const unsigned long esc_rate = clk_req->escclk_rate;
-	s32 ui, ui_x8, lpx;
+	s32 ui, ui_x8;
 	s32 tmax, tmin;
 	s32 pcnt0 = 50;
 	s32 pcnt1 = 50;
@@ -284,7 +283,6 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
 
 	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
 	ui_x8 = ui << 3;
-	lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
 
 	temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
 	tmin = max_t(s32, temp, 0);
commit c16c52a35e729cfc1f2b619fc208a6b3c23b9561
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Thu Oct 10 14:55:04 2019 +0800

    drm/msm/mdp5: Remove set but not used variable 'hw_cfg' in blend_setup
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c: In function blend_setup:
    drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c:225:28: warning: variable hw_cfg set but not used [-Wunused-but-set-variable]
    
    It is not used since commit 14be3200cd5f ("drm/msm: rename mdp->disp")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/1570690506-83287-3-git-send-email-zhengbin13@huawei.com

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index eb0b4b7dc7cc..05cc04f729d6 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -214,7 +214,6 @@ static void blend_setup(struct drm_crtc *crtc)
 	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
 	struct drm_plane *plane;
-	const struct mdp5_cfg_hw *hw_cfg;
 	struct mdp5_plane_state *pstate, *pstates[STAGE_MAX + 1] = {NULL};
 	const struct mdp_format *format;
 	struct mdp5_hw_mixer *mixer = pipeline->mixer;
@@ -232,8 +231,6 @@ static void blend_setup(struct drm_crtc *crtc)
 	u32 val;
 #define blender(stage)	((stage) - STAGE0)
 
-	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
-
 	spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
 
 	/* ctl could be released already when we are shutting down: */
commit 722525023b10910a753b6e212c7129ea9b5a9810
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Thu Oct 10 14:55:03 2019 +0800

    drm/msm/mdp5: Remove set but not used variable 'fmt'
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c: In function mdp5_smp_calculate:
    drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c:134:6: warning: variable fmt set but not used [-Wunused-but-set-variable]
    
    It is not used since commit 24c478ead0bf ("drm/fourcc:
    Pass the format_info pointer to drm_format_plane_cpp")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/1570690506-83287-2-git-send-email-zhengbin13@huawei.com

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index b31cfb554fa2..d7fa2c49e741 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -121,7 +121,6 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 	struct mdp5_kms *mdp5_kms = get_kms(smp);
 	int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
 	int i, hsub, nplanes, nlines;
-	u32 fmt = format->base.pixel_format;
 	uint32_t blkcfg = 0;
 
 	nplanes = info->num_planes;
@@ -135,7 +134,6 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 	 * them together, writes to SMP using a single client.
 	 */
 	if ((rev > 0) && (format->chroma_sample > CHROMA_FULL)) {
-		fmt = DRM_FORMAT_NV24;
 		nplanes = 2;
 
 		/* if decimation is enabled, HW decimates less on the
commit ab198a7aab65d6fcdbde082ff59a790dbf7e08f4
Author: Sean Paul <seanpaul at chromium.org>
Date:   Thu Oct 10 14:17:44 2019 -0400

    drm/msm: Sanitize the modeset_is_locked checks in dpu
    
    As Daniel mentions in his email [1], non-blocking commits don't hold the
    modeset locks, so we can safely access state as long as these functions
    are in the commit path. So remove the WARN_ON in dpu_kms_encoder_enable.
    
    In dpu_crtc_get_intf_mode, things are a bit more complicated. So keep
    the WARN_ON, but add a comment explaining the situation and hope someone
    comes along and fixes the issue.
    
    [1]- https://lists.freedesktop.org/archives/dri-devel/2019-October/239441.html
    
    Link to v1: https://patchwork.freedesktop.org/patch/msgid/20191010151351.126735-1-sean@poorly.run
    
    Changes in v2:
    - Restored the WARN_ON in get_intf_mode and added a clarifying comment (Daniel)
    
    Fixes: 1dfdb0e107db ("drm/msm: dpu: Add modeset lock checks where applicable")
    Cc: Jeykumar Sankaran <jsanka at codeaurora.org>
    Cc: Rob Clark <robdclark at chromium.org>
    Suggested-by: Daniel Vetter <daniel at ffwll.ch>
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/20191010181801.186069-1-sean@poorly.run

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 0b9dc042d2e2..f197dce54576 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -271,6 +271,15 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc)
 		return INTF_MODE_NONE;
 	}
 
+	/*
+	 * TODO: This function is called from dpu debugfs and as part of atomic
+	 * check. When called from debugfs, the crtc->mutex must be held to
+	 * read crtc->state. However reading crtc->state from atomic check isn't
+	 * allowed (unless you have a good reason, a big comment, and a deep
+	 * understanding of how the atomic/modeset locks work (<- and this is
+	 * probably not possible)). So we'll keep the WARN_ON here for now, but
+	 * really we need to figure out a better way to track our operating mode
+	 */
 	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
 
 	/* TODO: Returns the first INTF_MODE, could there be multiple values? */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index b1645ad83a1e..6c92f0fbeac9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -316,7 +316,6 @@ void dpu_kms_encoder_enable(struct drm_encoder *encoder)
 	if (funcs && funcs->commit)
 		funcs->commit(encoder);
 
-	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 	drm_for_each_crtc(crtc, dev) {
 		if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder)))
 			continue;
commit 8fbd534b7248f5d0311d9dbfd7b4749317e4395a
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Sat Oct 5 12:33:49 2019 +0800

    drm/msm/dpu: Remove set but not used variables 'mode', 'dpu_kms', 'priv'
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c: In function dpu_encoder_virt_disable:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c:1199:27: warning: variable mode set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c: In function _dpu_encoder_init_debugfs:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c:1963:18: warning: variable dpu_kms set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c: In function dpu_encoder_frame_done_timeout:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c:2183:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    
    They are not used since commit 25fdd5933e4c ("drm/msm:
    Add SDM845 DPU support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 85e7bacbce42..f96e142c4361 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1174,7 +1174,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
 	struct dpu_encoder_virt *dpu_enc = NULL;
 	struct msm_drm_private *priv;
 	struct dpu_kms *dpu_kms;
-	struct drm_display_mode *mode;
 	int i = 0;
 
 	if (!drm_enc) {
@@ -1191,8 +1190,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
 	mutex_lock(&dpu_enc->enc_lock);
 	dpu_enc->enabled = false;
 
-	mode = &drm_enc->crtc->state->adjusted_mode;
-
 	priv = drm_enc->dev->dev_private;
 	dpu_kms = to_dpu_kms(priv->kms);
 
commit 60b42f2ae69f5491eace2f8a3a6040be2deea34f
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Sat Oct 5 12:33:48 2019 +0800

    drm/msm/dpu: Remove set but not used variables 'cmd_enc', 'priv'
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c: In function dpu_encoder_phys_cmd_ctl_start_irq:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c:136:31: warning: variable cmd_enc set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c: In function dpu_encoder_phys_cmd_irq_control:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c:328:31: warning: variable cmd_enc set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c: In function dpu_encoder_phys_cmd_tearcheck_config:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c:367:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c: In function dpu_encoder_phys_cmd_wait_for_tx_complete:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c:662:31: warning: variable cmd_enc set but not used [-Wunused-but-set-variable]
    
    They are not used since commit 25fdd5933e4c ("drm/msm:
    Add SDM845 DPU support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index d5532836b5b9..047960949fbb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -124,13 +124,11 @@ static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
 static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx)
 {
 	struct dpu_encoder_phys *phys_enc = arg;
-	struct dpu_encoder_phys_cmd *cmd_enc;
 
 	if (!phys_enc || !phys_enc->hw_ctl)
 		return;
 
 	DPU_ATRACE_BEGIN("ctl_start_irq");
-	cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
 
 	atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
 
@@ -316,13 +314,9 @@ end:
 static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
 		bool enable)
 {
-	struct dpu_encoder_phys_cmd *cmd_enc;
-
 	if (!phys_enc)
 		return;
 
-	cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
-
 	trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
 			phys_enc->hw_pp->idx - PINGPONG_0,
 			enable, atomic_read(&phys_enc->vblank_refcount));
@@ -355,7 +349,6 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	struct drm_display_mode *mode;
 	bool tc_enable = true;
 	u32 vsync_hz;
-	struct msm_drm_private *priv;
 	struct dpu_kms *dpu_kms;
 
 	if (!phys_enc || !phys_enc->hw_pp) {
@@ -373,7 +366,6 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	}
 
 	dpu_kms = phys_enc->dpu_kms;
-	priv = dpu_kms->dev->dev_private;
 
 	/*
 	 * TE default: dsi byte clock calculated base on 70 fps;
@@ -646,13 +638,10 @@ static int dpu_encoder_phys_cmd_wait_for_tx_complete(
 		struct dpu_encoder_phys *phys_enc)
 {
 	int rc;
-	struct dpu_encoder_phys_cmd *cmd_enc;
 
 	if (!phys_enc)
 		return -EINVAL;
 
-	cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
-
 	rc = _dpu_encoder_phys_cmd_wait_for_idle(phys_enc);
 	if (rc) {
 		DRM_ERROR("failed wait_for_idle: id:%u ret:%d intf:%d\n",
commit f09662c1a6b44639fb25b8250249229dfaf207f7
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Sat Oct 5 12:33:47 2019 +0800

    drm/msm/dpu: Remove set but not used variables 'dpu_cstate', 'priv'
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c: In function dpu_core_perf_crtc_release_bw:
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c:248:25: warning: variable dpu_cstate set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c: In function dpu_core_perf_crtc_update:
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c:337:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    
    They are not used since commit 25fdd5933e4c ("drm/msm:
    Add SDM845 DPU support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index e96843010dff..11f2bebe3869 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -204,7 +204,6 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
 void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
 {
 	struct dpu_crtc *dpu_crtc;
-	struct dpu_crtc_state *dpu_cstate;
 	struct dpu_kms *kms;
 
 	if (!crtc) {
@@ -219,7 +218,6 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
 	}
 
 	dpu_crtc = to_dpu_crtc(crtc);
-	dpu_cstate = to_dpu_crtc_state(crtc->state);
 
 	if (atomic_dec_return(&kms->bandwidth_ref) > 0)
 		return;
@@ -276,7 +274,6 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 	u64 clk_rate = 0;
 	struct dpu_crtc *dpu_crtc;
 	struct dpu_crtc_state *dpu_cstate;
-	struct msm_drm_private *priv;
 	struct dpu_kms *kms;
 	int ret;
 
@@ -290,7 +287,6 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 		DPU_ERROR("invalid kms\n");
 		return -EINVAL;
 	}
-	priv = kms->dev->dev_private;
 
 	dpu_crtc = to_dpu_crtc(crtc);
 	dpu_cstate = to_dpu_crtc_state(crtc->state);
commit d4f1bec36c5db7ead9d098f23c0d22c52969d0fb
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Sat Oct 5 12:33:46 2019 +0800

    drm/msm/dpu: Remove set but not used variable 'priv' in dpu_core_irq.c
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c: In function dpu_core_irq_preinstall:
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c:354:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c: In function dpu_core_irq_uninstall:
    drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c:390:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    
    It is not used since commit 25fdd5933e4c ("drm/msm:
    Add SDM845 DPU support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
index 283d5a48fd13..f1bc6a1af7a7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -340,11 +340,8 @@ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms,
 
 void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 {
-	struct msm_drm_private *priv;
 	int i;
 
-	priv = dpu_kms->dev->dev_private;
-
 	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 	dpu_clear_all_irqs(dpu_kms);
 	dpu_disable_all_irqs(dpu_kms);
@@ -369,11 +366,8 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 
 void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 {
-	struct msm_drm_private *priv;
 	int i;
 
-	priv = dpu_kms->dev->dev_private;
-
 	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 	for (i = 0; i < dpu_kms->irq_obj.total_irqs; i++)
 		if (atomic_read(&dpu_kms->irq_obj.enable_counts[i]) ||
commit 3fa19069cd11ce9d86268164d8055fdd3ce1239b
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Sat Oct 5 12:33:45 2019 +0800

    drm/msm/dpu: Remove set but not used variable 'priv' in dpu_encoder_phys_vid.c
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c: In function dpu_encoder_phys_vid_disable:
    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c:566:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    
    It is not used since commit 25fdd5933e4c ("drm/msm:
    Add SDM845 DPU support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 15d21d7ec304..3123ef873cdf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -566,7 +566,6 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
 
 static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
 {
-	struct msm_drm_private *priv;
 	unsigned long lock_flags;
 	int ret;
 
@@ -574,7 +573,6 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
 		DPU_ERROR("invalid encoder/device\n");
 		return;
 	}
-	priv = phys_enc->parent->dev->dev_private;
 
 	if (!phys_enc->hw_intf || !phys_enc->hw_ctl) {
 		DPU_ERROR("invalid hw_intf %d hw_ctl %d\n",
commit a663a2b1350b68b62fc3162297bea18fb3ea2ab8
Author: zhengbin <zhengbin13 at huawei.com>
Date:   Sat Oct 5 12:33:44 2019 +0800

    drm/msm/dpu: Remove set but not used variable 'priv' in dpu_kms.c
    
    Fixes gcc '-Wunused-but-set-variable' warning:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c: In function _dpu_danger_signal_status:
    drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c:80:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c: In function dpu_kms_prepare_commit:
    drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c:271:26: warning: variable priv set but not used [-Wunused-but-set-variable]
    
    It is not used since commit 25fdd5933e4c ("drm/msm:
    Add SDM845 DPU support")
    
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: zhengbin <zhengbin13 at huawei.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 144bbbe3770b..b1645ad83a1e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -64,7 +64,6 @@ static int _dpu_danger_signal_status(struct seq_file *s,
 		bool danger_status)
 {
 	struct dpu_kms *kms = (struct dpu_kms *)s->private;
-	struct msm_drm_private *priv;
 	struct dpu_danger_safe_status status;
 	int i;
 
@@ -73,7 +72,6 @@ static int _dpu_danger_signal_status(struct seq_file *s,
 		return 0;
 	}
 
-	priv = kms->dev->dev_private;
 	memset(&status, 0, sizeof(struct dpu_danger_safe_status));
 
 	pm_runtime_get_sync(&kms->pdev->dev);
@@ -270,7 +268,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
 		struct drm_atomic_state *state)
 {
 	struct dpu_kms *dpu_kms;
-	struct msm_drm_private *priv;
 	struct drm_device *dev;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
@@ -281,7 +278,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
 		return;
 	dpu_kms = to_dpu_kms(kms);
 	dev = dpu_kms->dev;
-	priv = dev->dev_private;
 
 	/* Call prepare_commit for all affected encoders */
 	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
commit 70082a52f96a45650dfc3d8cdcd2c42bdac9f6f0
Author: Arnd Bergmann <arnd at arndb.de>
Date:   Wed Sep 18 21:57:07 2019 +0200

    drm/msm: include linux/sched/task.h
    
    Without this header file, compile-testing may run into a missing
    declaration:
    
    drivers/gpu/drm/msm/msm_gpu.c:444:4: error: implicit declaration of function 'put_task_struct' [-Werror,-Wimplicit-function-declaration]
    
    Fixes: 482f96324a4e ("drm/msm: Fix task dump in gpu recovery")
    Signed-off-by: Arnd Bergmann <arnd at arndb.de>
    Reviewed-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 122199af0381..18f3a5c53ffb 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -16,6 +16,7 @@
 #include <linux/pm_opp.h>
 #include <linux/devfreq.h>
 #include <linux/devcoredump.h>
+#include <linux/sched/task.h>
 
 /*
  * Power Management:
commit 5dce8d78207e929ff8f0e9dbe7180b23fed3651e
Author: Krzysztof Wilczynski <kw at linux.com>
Date:   Wed Sep 4 23:15:51 2019 +0200

    drm/msm/dsi: Move static keyword to the front of declarations
    
    Move the static keyword to the front of declarations
    of msm_dsi_v2_host_ops, msm_dsi_6g_host_ops and
    msm_dsi_6g_v2_host_ops, and resolve the following
    compiler warnings that can be seen when building
    with warnings enabled (W=1):
    
    drivers/gpu/drm/msm/dsi/dsi_cfg.c:150:1: warning:
      ‘static’ is not at beginning of declaration [-Wold-style-declaration]
    
    drivers/gpu/drm/msm/dsi/dsi_cfg.c:161:1: warning:
      ‘static’ is not at beginning of declaration [-Wold-style-declaration]
    
    drivers/gpu/drm/msm/dsi/dsi_cfg.c:172:1: warning:
      ‘static’ is not at beginning of declaration [-Wold-style-declaration]
    
    Signed-off-by: Krzysztof Wilczynski <kw at linux.com>
    Reviewed-by: Jeffrey Hugo <jeffrey.l.hugo at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index b7b7c1a9164a..e74dc8cc904b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -147,7 +147,7 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
 	.num_dsi = 2,
 };
 
-const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
+static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
 	.link_clk_enable = dsi_link_clk_enable_v2,
 	.link_clk_disable = dsi_link_clk_disable_v2,
 	.clk_init_ver = dsi_clk_init_v2,
@@ -158,7 +158,7 @@ const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
 	.calc_clk_rate = dsi_calc_clk_rate_v2,
 };
 
-const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
+static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
 	.link_clk_enable = dsi_link_clk_enable_6g,
 	.link_clk_disable = dsi_link_clk_disable_6g,
 	.clk_init_ver = NULL,
@@ -169,7 +169,7 @@ const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
 	.calc_clk_rate = dsi_calc_clk_rate_6g,
 };
 
-const static struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
+static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
 	.link_clk_enable = dsi_link_clk_enable_6g,
 	.link_clk_disable = dsi_link_clk_disable_6g,
 	.clk_init_ver = dsi_clk_init_6g_v2,
commit 53bf7f7a437a4120ec632183a21516609e18f4a5
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Mon Sep 16 14:11:54 2019 -0600

    drm/msm: Remove unused function arguments
    
    The arguments related to IOMMU port name have been unused since
    commit 944fc36c31ed ("drm/msm: use upstream iommu") and can be removed.
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index fbb154d7c81c..144bbbe3770b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -30,10 +30,6 @@
 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"
 
-static const char * const iommu_ports[] = {
-		"mdp_0",
-};
-
 /*
  * To enable overall DRM driver logging
  * # echo 0x2 > /sys/module/drm/parameters/debug
@@ -703,8 +699,7 @@ static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms)
 
 	mmu = dpu_kms->base.aspace->mmu;
 
-	mmu->funcs->detach(mmu, (const char **)iommu_ports,
-			ARRAY_SIZE(iommu_ports));
+	mmu->funcs->detach(mmu);
 	msm_gem_address_space_put(dpu_kms->base.aspace);
 
 	dpu_kms->base.aspace = NULL;
@@ -730,8 +725,7 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
 		return PTR_ERR(aspace);
 	}
 
-	ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
-			ARRAY_SIZE(iommu_ports));
+	ret = aspace->mmu->funcs->attach(aspace->mmu);
 	if (ret) {
 		DPU_ERROR("failed to attach iommu %d\n", ret);
 		msm_gem_address_space_put(aspace);
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index 50711ccc8691..dda05436f716 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -157,10 +157,6 @@ static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
 	}
 }
 
-static const char * const iommu_ports[] = {
-	"mdp_port0_cb0", "mdp_port1_cb0",
-};
-
 static void mdp4_destroy(struct msm_kms *kms)
 {
 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
@@ -172,8 +168,7 @@ static void mdp4_destroy(struct msm_kms *kms)
 	drm_gem_object_put_unlocked(mdp4_kms->blank_cursor_bo);
 
 	if (aspace) {
-		aspace->mmu->funcs->detach(aspace->mmu,
-				iommu_ports, ARRAY_SIZE(iommu_ports));
+		aspace->mmu->funcs->detach(aspace->mmu);
 		msm_gem_address_space_put(aspace);
 	}
 
@@ -524,8 +519,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
 
 		kms->aspace = aspace;
 
-		ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
-				ARRAY_SIZE(iommu_ports));
+		ret = aspace->mmu->funcs->attach(aspace->mmu);
 		if (ret)
 			goto fail;
 	} else {
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 91cd76a2bab1..f8bd0bfcf4b0 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -19,10 +19,6 @@
 #include "msm_mmu.h"
 #include "mdp5_kms.h"
 
-static const char *iommu_ports[] = {
-		"mdp_0",
-};
-
 static int mdp5_hw_init(struct msm_kms *kms)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -233,8 +229,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
 		mdp5_pipe_destroy(mdp5_kms->hwpipes[i]);
 
 	if (aspace) {
-		aspace->mmu->funcs->detach(aspace->mmu,
-				iommu_ports, ARRAY_SIZE(iommu_ports));
+		aspace->mmu->funcs->detach(aspace->mmu);
 		msm_gem_address_space_put(aspace);
 	}
 }
@@ -737,8 +732,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 
 		kms->aspace = aspace;
 
-		ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
-				ARRAY_SIZE(iommu_ports));
+		ret = aspace->mmu->funcs->attach(aspace->mmu);
 		if (ret) {
 			DRM_DEV_ERROR(&pdev->dev, "failed to attach iommu: %d\n",
 				ret);
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index a052364a5d74..122199af0381 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -838,7 +838,7 @@ msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
 		return ERR_CAST(aspace);
 	}
 
-	ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0);
+	ret = aspace->mmu->funcs->attach(aspace->mmu);
 	if (ret) {
 		msm_gem_address_space_put(aspace);
 		return ERR_PTR(ret);
@@ -995,8 +995,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
 	msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace, false);
 
 	if (!IS_ERR_OR_NULL(gpu->aspace)) {
-		gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
-			NULL, 0);
+		gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu);
 		msm_gem_address_space_put(gpu->aspace);
 	}
 }
diff --git a/drivers/gpu/drm/msm/msm_gpummu.c b/drivers/gpu/drm/msm/msm_gpummu.c
index 34f643a0c28a..34980d8eb7ad 100644
--- a/drivers/gpu/drm/msm/msm_gpummu.c
+++ b/drivers/gpu/drm/msm/msm_gpummu.c
@@ -21,14 +21,12 @@ struct msm_gpummu {
 #define GPUMMU_PAGE_SIZE SZ_4K
 #define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE)
 
-static int msm_gpummu_attach(struct msm_mmu *mmu, const char * const *names,
-		int cnt)
+static int msm_gpummu_attach(struct msm_mmu *mmu)
 {
 	return 0;
 }
 
-static void msm_gpummu_detach(struct msm_mmu *mmu, const char * const *names,
-		int cnt)
+static void msm_gpummu_detach(struct msm_mmu *mmu)
 {
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 8c95c31e2b12..ad58cfe5998e 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -23,16 +23,14 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
 	return 0;
 }
 
-static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names,
-			    int cnt)
+static int msm_iommu_attach(struct msm_mmu *mmu)
 {
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 
 	return iommu_attach_device(iommu->domain, mmu->dev);
 }
 
-static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names,
-			     int cnt)
+static void msm_iommu_detach(struct msm_mmu *mmu)
 {
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index 871d56303697..67a623f14319 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -10,8 +10,8 @@
 #include <linux/iommu.h>
 
 struct msm_mmu_funcs {
-	int (*attach)(struct msm_mmu *mmu, const char * const *names, int cnt);
-	void (*detach)(struct msm_mmu *mmu, const char * const *names, int cnt);
+	int (*attach)(struct msm_mmu *mmu);
+	void (*detach)(struct msm_mmu *mmu);
 	int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
 			unsigned len, int prot);
 	int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len);
commit fa8278b89dfb2d7df1cb7898c5842d90ce52c7bd
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Fri Sep 6 13:23:44 2019 -0600

    drm/msm/dpu: Remove unnecessary NULL checks
    
    dpu_kms.dev will never be NULL, so don't bother checking.
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
index a53517abf15c..283d5a48fd13 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -343,10 +343,6 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 	struct msm_drm_private *priv;
 	int i;
 
-	if (!dpu_kms->dev) {
-		DPU_ERROR("invalid drm device\n");
-		return;
-	}
 	priv = dpu_kms->dev->dev_private;
 
 	pm_runtime_get_sync(&dpu_kms->pdev->dev);
@@ -376,10 +372,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 	struct msm_drm_private *priv;
 	int i;
 
-	if (!dpu_kms->dev) {
-		DPU_ERROR("invalid drm device\n");
-		return;
-	}
 	priv = dpu_kms->dev->dev_private;
 
 	pm_runtime_get_sync(&dpu_kms->pdev->dev);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 39fc39cd2439..d5532836b5b9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -373,10 +373,6 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	}
 
 	dpu_kms = phys_enc->dpu_kms;
-	if (!dpu_kms->dev) {
-		DPU_ERROR("invalid device\n");
-		return;
-	}
 	priv = dpu_kms->dev->dev_private;
 
 	/*
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 9d6429fa6229..fbb154d7c81c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -72,7 +72,7 @@ static int _dpu_danger_signal_status(struct seq_file *s,
 	struct dpu_danger_safe_status status;
 	int i;
 
-	if (!kms->dev || !kms->hw_mdp) {
+	if (!kms->hw_mdp) {
 		DPU_ERROR("invalid arg(s)\n");
 		return 0;
 	}
@@ -153,9 +153,6 @@ static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
 		return 0;
 
 	dev = dpu_kms->dev;
-	if (!dev)
-		return 0;
-
 	priv = dev->dev_private;
 	base = dpu_kms->mmio + regset->offset;
 
@@ -288,9 +285,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
 		return;
 	dpu_kms = to_dpu_kms(kms);
 	dev = dpu_kms->dev;
-
-	if (!dev)
-		return;
 	priv = dev->dev_private;
 
 	/* Call prepare_commit for all affected encoders */
@@ -461,10 +455,6 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
 	struct msm_drm_private *priv;
 	int i;
 
-	if (!dpu_kms->dev) {
-		DPU_ERROR("invalid dev\n");
-		return;
-	}
 	priv = dpu_kms->dev->dev_private;
 
 	for (i = 0; i < priv->num_crtcs; i++)
@@ -496,7 +486,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 
 	int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret;
 	int max_crtc_count;
-
 	dev = dpu_kms->dev;
 	priv = dev->dev_private;
 	catalog = dpu_kms->catalog;
@@ -576,8 +565,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
 	int i;
 
 	dev = dpu_kms->dev;
-	if (!dev)
-		return;
 
 	if (dpu_kms->hw_intr)
 		dpu_hw_intr_destroy(dpu_kms->hw_intr);
@@ -794,11 +781,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 
 	dpu_kms = to_dpu_kms(kms);
 	dev = dpu_kms->dev;
-	if (!dev) {
-		DPU_ERROR("invalid device\n");
-		return rc;
-	}
-
 	priv = dev->dev_private;
 
 	atomic_set(&dpu_kms->bandwidth_ref, 0);
@@ -1051,11 +1033,6 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev)
 	struct dss_module_power *mp = &dpu_kms->mp;
 
 	ddev = dpu_kms->dev;
-	if (!ddev) {
-		DPU_ERROR("invalid drm_device\n");
-		return rc;
-	}
-
 	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
 	if (rc)
 		DPU_ERROR("clock disable failed rc:%d\n", rc);
@@ -1073,11 +1050,6 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev)
 	struct dss_module_power *mp = &dpu_kms->mp;
 
 	ddev = dpu_kms->dev;
-	if (!ddev) {
-		DPU_ERROR("invalid drm_device\n");
-		return rc;
-	}
-
 	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
 	if (rc) {
 		DPU_ERROR("clock enable failed rc:%d\n", rc);
commit 966301400402103ce6fc16cbb70a8545d3dceb76
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Fri Sep 6 13:23:43 2019 -0600

    drm/msm/dpu: Remove unnecessary NULL checks
    
    msm_drm_private.kms will only be NULL in the dummy headless case, so
    there is no need to check it in the dpu display driver.
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
index 17f917b718ce..a53517abf15c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -55,8 +55,7 @@ static void dpu_core_irq_callback_handler(void *arg, int irq_idx)
 int dpu_core_irq_idx_lookup(struct dpu_kms *dpu_kms,
 		enum dpu_intr_type intr_type, u32 instance_idx)
 {
-	if (!dpu_kms || !dpu_kms->hw_intr ||
-			!dpu_kms->hw_intr->ops.irq_idx_lookup)
+	if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.irq_idx_lookup)
 		return -EINVAL;
 
 	return dpu_kms->hw_intr->ops.irq_idx_lookup(intr_type,
@@ -73,7 +72,7 @@ static int _dpu_core_irq_enable(struct dpu_kms *dpu_kms, int irq_idx)
 	unsigned long irq_flags;
 	int ret = 0, enable_count;
 
-	if (!dpu_kms || !dpu_kms->hw_intr ||
+	if (!dpu_kms->hw_intr ||
 			!dpu_kms->irq_obj.enable_counts ||
 			!dpu_kms->irq_obj.irq_counts) {
 		DPU_ERROR("invalid params\n");
@@ -114,7 +113,7 @@ int dpu_core_irq_enable(struct dpu_kms *dpu_kms, int *irq_idxs, u32 irq_count)
 {
 	int i, ret = 0, counts;
 
-	if (!dpu_kms || !irq_idxs || !irq_count) {
+	if (!irq_idxs || !irq_count) {
 		DPU_ERROR("invalid params\n");
 		return -EINVAL;
 	}
@@ -138,7 +137,7 @@ static int _dpu_core_irq_disable(struct dpu_kms *dpu_kms, int irq_idx)
 {
 	int ret = 0, enable_count;
 
-	if (!dpu_kms || !dpu_kms->hw_intr || !dpu_kms->irq_obj.enable_counts) {
+	if (!dpu_kms->hw_intr || !dpu_kms->irq_obj.enable_counts) {
 		DPU_ERROR("invalid params\n");
 		return -EINVAL;
 	}
@@ -169,7 +168,7 @@ int dpu_core_irq_disable(struct dpu_kms *dpu_kms, int *irq_idxs, u32 irq_count)
 {
 	int i, ret = 0, counts;
 
-	if (!dpu_kms || !irq_idxs || !irq_count) {
+	if (!irq_idxs || !irq_count) {
 		DPU_ERROR("invalid params\n");
 		return -EINVAL;
 	}
@@ -186,7 +185,7 @@ int dpu_core_irq_disable(struct dpu_kms *dpu_kms, int *irq_idxs, u32 irq_count)
 
 u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx, bool clear)
 {
-	if (!dpu_kms || !dpu_kms->hw_intr ||
+	if (!dpu_kms->hw_intr ||
 			!dpu_kms->hw_intr->ops.get_interrupt_status)
 		return 0;
 
@@ -205,7 +204,7 @@ int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, int irq_idx,
 {
 	unsigned long irq_flags;
 
-	if (!dpu_kms || !dpu_kms->irq_obj.irq_cb_tbl) {
+	if (!dpu_kms->irq_obj.irq_cb_tbl) {
 		DPU_ERROR("invalid params\n");
 		return -EINVAL;
 	}
@@ -240,7 +239,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx,
 {
 	unsigned long irq_flags;
 
-	if (!dpu_kms || !dpu_kms->irq_obj.irq_cb_tbl) {
+	if (!dpu_kms->irq_obj.irq_cb_tbl) {
 		DPU_ERROR("invalid params\n");
 		return -EINVAL;
 	}
@@ -274,8 +273,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx,
 
 static void dpu_clear_all_irqs(struct dpu_kms *dpu_kms)
 {
-	if (!dpu_kms || !dpu_kms->hw_intr ||
-			!dpu_kms->hw_intr->ops.clear_all_irqs)
+	if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.clear_all_irqs)
 		return;
 
 	dpu_kms->hw_intr->ops.clear_all_irqs(dpu_kms->hw_intr);
@@ -283,8 +281,7 @@ static void dpu_clear_all_irqs(struct dpu_kms *dpu_kms)
 
 static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms)
 {
-	if (!dpu_kms || !dpu_kms->hw_intr ||
-			!dpu_kms->hw_intr->ops.disable_all_irqs)
+	if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.disable_all_irqs)
 		return;
 
 	dpu_kms->hw_intr->ops.disable_all_irqs(dpu_kms->hw_intr);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 839887a3a80c..e96843010dff 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -32,13 +32,7 @@ enum dpu_perf_mode {
 static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
 {
 	struct msm_drm_private *priv;
-
 	priv = crtc->dev->dev_private;
-	if (!priv->kms) {
-		DPU_ERROR("invalid kms\n");
-		return NULL;
-	}
-
 	return to_dpu_kms(priv->kms);
 }
 
@@ -111,7 +105,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
 	}
 
 	kms = _dpu_crtc_get_kms(crtc);
-	if (!kms || !kms->catalog) {
+	if (!kms->catalog) {
 		DPU_ERROR("invalid parameters\n");
 		return 0;
 	}
@@ -219,7 +213,7 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
 	}
 
 	kms = _dpu_crtc_get_kms(crtc);
-	if (!kms || !kms->catalog) {
+	if (!kms->catalog) {
 		DPU_ERROR("invalid kms\n");
 		return;
 	}
@@ -292,7 +286,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 	}
 
 	kms = _dpu_crtc_get_kms(crtc);
-	if (!kms || !kms->catalog) {
+	if (!kms->catalog) {
 		DPU_ERROR("invalid kms\n");
 		return -EINVAL;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 7b37d1eeeab5..85e7bacbce42 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -645,11 +645,6 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
 	priv = drm_enc->dev->dev_private;
 
 	dpu_kms = to_dpu_kms(priv->kms);
-	if (!dpu_kms) {
-		DPU_ERROR("invalid dpu_kms\n");
-		return;
-	}
-
 	hw_mdptop = dpu_kms->hw_mdp;
 	if (!hw_mdptop) {
 		DPU_ERROR("invalid mdptop\n");
@@ -1098,10 +1093,6 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
 
 	priv = drm_enc->dev->dev_private;
 	dpu_kms = to_dpu_kms(priv->kms);
-	if (!dpu_kms) {
-		DPU_ERROR("invalid dpu_kms\n");
-		return;
-	}
 
 	dpu_enc = to_dpu_encoder_virt(drm_enc);
 	if (!dpu_enc || !dpu_enc->cur_master) {
@@ -2032,9 +2023,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
 	enum dpu_intf_type intf_type;
 	struct dpu_enc_phys_init_params phys_params;
 
-	if (!dpu_enc || !dpu_kms) {
-		DPU_ERROR("invalid arg(s), enc %d kms %d\n",
-				dpu_enc != 0, dpu_kms != 0);
+	if (!dpu_enc) {
+		DPU_ERROR("invalid arg(s), enc %d\n", dpu_enc != 0);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 50fe1ed7095c..39fc39cd2439 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -373,7 +373,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	}
 
 	dpu_kms = phys_enc->dpu_kms;
-	if (!dpu_kms || !dpu_kms->dev) {
+	if (!dpu_kms->dev) {
 		DPU_ERROR("invalid device\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index bd333d957add..15d21d7ec304 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -374,7 +374,7 @@ static void dpu_encoder_phys_vid_mode_set(
 		struct drm_display_mode *mode,
 		struct drm_display_mode *adj_mode)
 {
-	if (!phys_enc || !phys_enc->dpu_kms) {
+	if (!phys_enc) {
 		DPU_ERROR("invalid encoder/kms\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 4a69d8ecf5e1..9d6429fa6229 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -461,10 +461,7 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
 	struct msm_drm_private *priv;
 	int i;
 
-	if (!dpu_kms) {
-		DPU_ERROR("invalid dpu_kms\n");
-		return;
-	} else if (!dpu_kms->dev) {
+	if (!dpu_kms->dev) {
 		DPU_ERROR("invalid dev\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
index 8d24b79fd400..991f4c8f8a12 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -154,10 +154,6 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
 	u32 ot_lim;
 	int ret, i;
 
-	if (!dpu_kms) {
-		DPU_ERROR("invalid arguments\n");
-		return;
-	}
 	mdp = dpu_kms->hw_mdp;
 
 	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
@@ -214,7 +210,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
 	const struct dpu_vbif_qos_tbl *qos_tbl;
 	int i;
 
-	if (!dpu_kms || !params || !dpu_kms->hw_mdp) {
+	if (!params || !dpu_kms->hw_mdp) {
 		DPU_ERROR("invalid arguments\n");
 		return;
 	}
commit c3739878a9e511d272358d5821d073795ead7c61
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Fri Sep 6 13:23:42 2019 -0600

    drm/msm/dpu: Remove unnecessary NULL checks
    
    drm_crtc.dev will never be NULL, so no need to check it.
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 094d74635fb7..839887a3a80c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -33,11 +33,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
 {
 	struct msm_drm_private *priv;
 
-	if (!crtc->dev) {
-		DPU_ERROR("invalid device\n");
-		return NULL;
-	}
-
 	priv = crtc->dev->dev_private;
 	if (!priv->kms) {
 		DPU_ERROR("invalid kms\n");
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index ead7d657097c..0b9dc042d2e2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -266,7 +266,7 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc)
 {
 	struct drm_encoder *encoder;
 
-	if (!crtc || !crtc->dev) {
+	if (!crtc) {
 		DPU_ERROR("invalid crtc\n");
 		return INTF_MODE_NONE;
 	}
@@ -694,7 +694,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 	unsigned long flags;
 	bool release_bandwidth = false;
 
-	if (!crtc || !crtc->dev || !crtc->state) {
+	if (!crtc || !crtc->state) {
 		DPU_ERROR("invalid crtc\n");
 		return;
 	}
@@ -766,7 +766,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
 	struct msm_drm_private *priv;
 	bool request_bandwidth;
 
-	if (!crtc || !crtc->dev) {
+	if (!crtc) {
 		DPU_ERROR("invalid crtc\n");
 		return;
 	}
commit 422ed75581176ca8be2c87ea1c3720608dc46212
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Fri Sep 6 13:23:41 2019 -0600

    drm/msm/dpu: Remove unnecessary NULL checks
    
    drm_device.dev_private is set to a non-NULL msm_drm_private
    struct in msm_drm_init. Successful initialization of msm means
    that dev_private is non-NULL so there is no need to check it
    everywhere.
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
index cdbea38b8697..17f917b718ce 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -349,9 +349,6 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 	if (!dpu_kms->dev) {
 		DPU_ERROR("invalid drm device\n");
 		return;
-	} else if (!dpu_kms->dev->dev_private) {
-		DPU_ERROR("invalid device private\n");
-		return;
 	}
 	priv = dpu_kms->dev->dev_private;
 
@@ -385,9 +382,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 	if (!dpu_kms->dev) {
 		DPU_ERROR("invalid drm device\n");
 		return;
-	} else if (!dpu_kms->dev->dev_private) {
-		DPU_ERROR("invalid device private\n");
-		return;
 	}
 	priv = dpu_kms->dev->dev_private;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 09a49b59bb5b..094d74635fb7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -33,13 +33,13 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
 {
 	struct msm_drm_private *priv;
 
-	if (!crtc->dev || !crtc->dev->dev_private) {
+	if (!crtc->dev) {
 		DPU_ERROR("invalid device\n");
 		return NULL;
 	}
 
 	priv = crtc->dev->dev_private;
-	if (!priv || !priv->kms) {
+	if (!priv->kms) {
 		DPU_ERROR("invalid kms\n");
 		return NULL;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 2ece11262943..ead7d657097c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -694,7 +694,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 	unsigned long flags;
 	bool release_bandwidth = false;
 
-	if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) {
+	if (!crtc || !crtc->dev || !crtc->state) {
 		DPU_ERROR("invalid crtc\n");
 		return;
 	}
@@ -766,7 +766,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
 	struct msm_drm_private *priv;
 	bool request_bandwidth;
 
-	if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
+	if (!crtc || !crtc->dev) {
 		DPU_ERROR("invalid crtc\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 4d2cacd0ce3d..7b37d1eeeab5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -735,8 +735,7 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc,
 	struct msm_drm_private *priv;
 	bool is_vid_mode = false;
 
-	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
-			!drm_enc->crtc) {
+	if (!drm_enc || !drm_enc->dev || !drm_enc->crtc) {
 		DPU_ERROR("invalid parameters\n");
 		return -EINVAL;
 	}
@@ -1092,7 +1091,7 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
 	struct msm_drm_private *priv;
 	struct dpu_kms *dpu_kms;
 
-	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
+	if (!drm_enc || !drm_enc->dev) {
 		DPU_ERROR("invalid parameters\n");
 		return;
 	}
@@ -1193,9 +1192,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
 	} else if (!drm_enc->dev) {
 		DPU_ERROR("invalid dev\n");
 		return;
-	} else if (!drm_enc->dev->dev_private) {
-		DPU_ERROR("invalid dev_private\n");
-		return;
 	}
 
 	dpu_enc = to_dpu_encoder_virt(drm_enc);
@@ -1734,8 +1730,7 @@ static void dpu_encoder_vsync_event_handler(struct timer_list *t)
 	struct msm_drm_private *priv;
 	struct msm_drm_thread *event_thread;
 
-	if (!drm_enc->dev || !drm_enc->dev->dev_private ||
-			!drm_enc->crtc) {
+	if (!drm_enc->dev || !drm_enc->crtc) {
 		DPU_ERROR("invalid parameters\n");
 		return;
 	}
@@ -1925,7 +1920,7 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
 
 	char name[DPU_NAME_SIZE];
 
-	if (!drm_enc->dev || !drm_enc->dev->dev_private) {
+	if (!drm_enc->dev) {
 		DPU_ERROR("invalid encoder or kms\n");
 		return -EINVAL;
 	}
@@ -2130,7 +2125,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
 	struct drm_encoder *drm_enc = &dpu_enc->base;
 	u32 event;
 
-	if (!drm_enc->dev || !drm_enc->dev->dev_private) {
+	if (!drm_enc->dev) {
 		DPU_ERROR("invalid parameters\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 2923b63d95fe..50fe1ed7095c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -373,7 +373,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	}
 
 	dpu_kms = phys_enc->dpu_kms;
-	if (!dpu_kms || !dpu_kms->dev || !dpu_kms->dev->dev_private) {
+	if (!dpu_kms || !dpu_kms->dev) {
 		DPU_ERROR("invalid device\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index b9c84fb4d4a1..bd333d957add 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -570,8 +570,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
 	unsigned long lock_flags;
 	int ret;
 
-	if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev ||
-			!phys_enc->parent->dev->dev_private) {
+	if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev) {
 		DPU_ERROR("invalid encoder/device\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 58b0485dc375..4a69d8ecf5e1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -72,7 +72,7 @@ static int _dpu_danger_signal_status(struct seq_file *s,
 	struct dpu_danger_safe_status status;
 	int i;
 
-	if (!kms->dev || !kms->dev->dev_private || !kms->hw_mdp) {
+	if (!kms->dev || !kms->hw_mdp) {
 		DPU_ERROR("invalid arg(s)\n");
 		return 0;
 	}
@@ -157,9 +157,6 @@ static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
 		return 0;
 
 	priv = dev->dev_private;
-	if (!priv)
-		return 0;
-
 	base = dpu_kms->mmio + regset->offset;
 
 	/* insert padding spaces, if needed */
@@ -292,7 +289,7 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
 	dpu_kms = to_dpu_kms(kms);
 	dev = dpu_kms->dev;
 
-	if (!dev || !dev->dev_private)
+	if (!dev)
 		return;
 	priv = dev->dev_private;
 
@@ -470,9 +467,6 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
 	} else if (!dpu_kms->dev) {
 		DPU_ERROR("invalid dev\n");
 		return;
-	} else if (!dpu_kms->dev->dev_private) {
-		DPU_ERROR("invalid dev_private\n");
-		return;
 	}
 	priv = dpu_kms->dev->dev_private;
 
@@ -809,10 +803,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 	}
 
 	priv = dev->dev_private;
-	if (!priv) {
-		DPU_ERROR("invalid private data\n");
-		return rc;
-	}
 
 	atomic_set(&dpu_kms->bandwidth_ref, 0);
 
@@ -974,7 +964,7 @@ struct msm_kms *dpu_kms_init(struct drm_device *dev)
 	struct dpu_kms *dpu_kms;
 	int irq;
 
-	if (!dev || !dev->dev_private) {
+	if (!dev) {
 		DPU_ERROR("drm device node invalid\n");
 		return ERR_PTR(-EINVAL);
 	}
commit c3b80b28c1744d233cf2763f87a7b321af7338d0
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Fri Sep 6 13:23:40 2019 -0600

    drm/msm/dpu: Remove unused macro
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 4c889aabdaf9..6ceba33a179e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -139,10 +139,6 @@ struct vsync_info {
 
 #define to_dpu_kms(x) container_of(x, struct dpu_kms, base)
 
-/* get struct msm_kms * from drm_device * */
-#define ddev_to_msm_kms(D) ((D) && (D)->dev_private ? \
-		((struct msm_drm_private *)((D)->dev_private))->kms : NULL)
-
 /**
  * Debugfs functions - extra helper functions for debugfs support
  *
commit e5c8d1b2c1831bd69619eb52cb3bbd0eb4f92956
Author: Drew Davenport <ddavenport at chromium.org>
Date:   Fri Sep 6 13:23:39 2019 -0600

    drm/msm/dpu: Remove unused variables
    
    Signed-off-by: Drew Davenport <ddavenport at chromium.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index ce59adff06aa..2ece11262943 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1288,13 +1288,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
 {
 	struct drm_crtc *crtc = NULL;
 	struct dpu_crtc *dpu_crtc = NULL;
-	struct msm_drm_private *priv = NULL;
-	struct dpu_kms *kms = NULL;
 	int i;
 
-	priv = dev->dev_private;
-	kms = to_dpu_kms(priv->kms);
-
 	dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL);
 	if (!dpu_crtc)
 		return ERR_PTR(-ENOMEM);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index d82ea994063f..4d2cacd0ce3d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1914,8 +1914,6 @@ static int _dpu_encoder_debugfs_status_open(struct inode *inode,
 static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
 {
 	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
-	struct msm_drm_private *priv;
-	struct dpu_kms *dpu_kms;
 	int i;
 
 	static const struct file_operations debugfs_status_fops = {
@@ -1932,9 +1930,6 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
 		return -EINVAL;
 	}
 
-	priv = drm_enc->dev->dev_private;
-	dpu_kms = to_dpu_kms(priv->kms);
-
 	snprintf(name, DPU_NAME_SIZE, "encoder%u", drm_enc->base.id);
 
 	/* create overall sub-directory for the encoder */
@@ -2133,14 +2128,12 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
 	struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t,
 			frame_done_timer);
 	struct drm_encoder *drm_enc = &dpu_enc->base;
-	struct msm_drm_private *priv;
 	u32 event;
 
 	if (!drm_enc->dev || !drm_enc->dev->dev_private) {
 		DPU_ERROR("invalid parameters\n");
 		return;
 	}
-	priv = drm_enc->dev->dev_private;
 
 	if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc_frame_event_cb) {
 		DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n",
commit bfcb7e1555ecc157cea23e35057002e3055e90a6
Author: Brian Masney <masneyb at onstation.org>
Date:   Sun Sep 1 17:30:37 2019 -0400

    soc: qcom: ocmem: add missing includes
    
    The kbuild bot reported the following compiler errors when compiling on
    MIPS with CONFIG_QCOM_OCMEM disabled:
    
      In file included from <command-line>:0:0:
      >> include/soc/qcom/ocmem.h:43:49: warning: 'struct device' declared
         inside parameter list will not be visible outside of this
         definition or declaration
          static inline struct ocmem *of_get_ocmem(struct device *dev)
                                                          ^~~~~~
         include/soc/qcom/ocmem.h: In function 'of_get_ocmem':
      >> include/soc/qcom/ocmem.h:45:9: error: implicit declaration of
         function 'ERR_PTR' [-Werror=implicit-function-declaration]
           return ERR_PTR(-ENODEV);
                  ^~~~~~~
      >> include/soc/qcom/ocmem.h:45:18: error: 'ENODEV' undeclared (first
         use in this function)
           return ERR_PTR(-ENODEV);
    
    Add the proper includes to fix the compiler errors.
    
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reported-by: kbuild test robot <lkp at intel.com>
    Tested-by: Gabriel Francisco <frc.gabriel at gmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/include/soc/qcom/ocmem.h b/include/soc/qcom/ocmem.h
index a0ae336ba78b..02a8bc2677b1 100644
--- a/include/soc/qcom/ocmem.h
+++ b/include/soc/qcom/ocmem.h
@@ -9,6 +9,9 @@
  * Copyright (C) 2015 Red Hat. Author: Rob Clark <robdclark at gmail.com>
  */
 
+#include <linux/device.h>
+#include <linux/err.h>
+
 #ifndef __OCMEM_H__
 #define __OCMEM_H__
 
commit 26c0b26dcd005d9d6de9246737177e7af821859a
Author: Brian Masney <masneyb at onstation.org>
Date:   Fri Aug 23 05:16:36 2019 -0700

    drm/msm/gpu: add ocmem init/cleanup functions
    
    The files a3xx_gpu.c and a4xx_gpu.c have ifdefs for the OCMEM support
    that was missing upstream. Add two new functions (adreno_gpu_ocmem_init
    and adreno_gpu_ocmem_cleanup) that removes some duplicated code.
    
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reviewed-by: Jordan Crouse <jcrouse at codeaurora.org>
    Tested-by: Gabriel Francisco <frc.gabrielgmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index e9160ce39cbb..6deaa7d01654 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -7,6 +7,7 @@ config DRM_MSM
 	depends on OF && COMMON_CLK
 	depends on MMU
 	depends on INTERCONNECT || !INTERCONNECT
+	depends on QCOM_OCMEM || QCOM_OCMEM=n
 	select QCOM_MDT_LOADER if ARCH_QCOM
 	select REGULATOR
 	select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 5f7e98028eaf..7ad14937fcdf 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -6,10 +6,6 @@
  * Copyright (c) 2014 The Linux Foundation. All rights reserved.
  */
 
-#ifdef CONFIG_MSM_OCMEM
-#  include <mach/ocmem.h>
-#endif
-
 #include "a3xx_gpu.h"
 
 #define A3XX_INT0_MASK \
@@ -195,9 +191,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
 		gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x00000000);
 
 	/* Set the OCMEM base address for A330, etc */
-	if (a3xx_gpu->ocmem_hdl) {
+	if (a3xx_gpu->ocmem.hdl) {
 		gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR,
-			(unsigned int)(a3xx_gpu->ocmem_base >> 14));
+			(unsigned int)(a3xx_gpu->ocmem.base >> 14));
 	}
 
 	/* Turn on performance counters: */
@@ -318,10 +314,7 @@ static void a3xx_destroy(struct msm_gpu *gpu)
 
 	adreno_gpu_cleanup(adreno_gpu);
 
-#ifdef CONFIG_MSM_OCMEM
-	if (a3xx_gpu->ocmem_base)
-		ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl);
-#endif
+	adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem);
 
 	kfree(a3xx_gpu);
 }
@@ -494,17 +487,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
 
 	/* if needed, allocate gmem: */
 	if (adreno_is_a330(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-		/* TODO this is different/missing upstream: */
-		struct ocmem_buf *ocmem_hdl =
-				ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
-
-		a3xx_gpu->ocmem_hdl = ocmem_hdl;
-		a3xx_gpu->ocmem_base = ocmem_hdl->addr;
-		adreno_gpu->gmem = ocmem_hdl->len;
-		DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
-				a3xx_gpu->ocmem_base);
-#endif
+		ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev,
+					    adreno_gpu, &a3xx_gpu->ocmem);
+		if (ret)
+			goto fail;
 	}
 
 	if (!gpu->aspace) {
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
index 5dc33e5ea53b..c555fb13e0d7 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
@@ -19,8 +19,7 @@ struct a3xx_gpu {
 	struct adreno_gpu base;
 
 	/* if OCMEM is used for GMEM: */
-	uint32_t ocmem_base;
-	void *ocmem_hdl;
+	struct adreno_ocmem ocmem;
 };
 #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base)
 
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index ab2b752566d8..b01388a9e89e 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -2,9 +2,6 @@
 /* Copyright (c) 2014 The Linux Foundation. All rights reserved.
  */
 #include "a4xx_gpu.h"
-#ifdef CONFIG_MSM_OCMEM
-#  include <soc/qcom/ocmem.h>
-#endif
 
 #define A4XX_INT0_MASK \
 	(A4XX_INT0_RBBM_AHB_ERROR |        \
@@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
 			(1 << 30) | 0xFFFF);
 
 	gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR,
-			(unsigned int)(a4xx_gpu->ocmem_base >> 14));
+			(unsigned int)(a4xx_gpu->ocmem.base >> 14));
 
 	/* Turn on performance counters: */
 	gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01);
@@ -318,10 +315,7 @@ static void a4xx_destroy(struct msm_gpu *gpu)
 
 	adreno_gpu_cleanup(adreno_gpu);
 
-#ifdef CONFIG_MSM_OCMEM
-	if (a4xx_gpu->ocmem_base)
-		ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl);
-#endif
+	adreno_gpu_ocmem_cleanup(&a4xx_gpu->ocmem);
 
 	kfree(a4xx_gpu);
 }
@@ -578,17 +572,10 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
 
 	/* if needed, allocate gmem: */
 	if (adreno_is_a4xx(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-		/* TODO this is different/missing upstream: */
-		struct ocmem_buf *ocmem_hdl =
-				ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
-
-		a4xx_gpu->ocmem_hdl = ocmem_hdl;
-		a4xx_gpu->ocmem_base = ocmem_hdl->addr;
-		adreno_gpu->gmem = ocmem_hdl->len;
-		DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
-				a4xx_gpu->ocmem_base);
-#endif
+		ret = adreno_gpu_ocmem_init(dev->dev, adreno_gpu,
+					    &a4xx_gpu->ocmem);
+		if (ret)
+			goto fail;
 	}
 
 	if (!gpu->aspace) {
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
index d506311ee240..a01448cba2ea 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
@@ -16,8 +16,7 @@ struct a4xx_gpu {
 	struct adreno_gpu base;
 
 	/* if OCMEM is used for GMEM: */
-	uint32_t ocmem_base;
-	void *ocmem_hdl;
+	struct adreno_ocmem ocmem;
 };
 #define to_a4xx_gpu(x) container_of(x, struct a4xx_gpu, base)
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 048c8be426f3..0783e4b5486a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -14,6 +14,7 @@
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
 #include <linux/soc/qcom/mdt_loader.h>
+#include <soc/qcom/ocmem.h>
 #include "adreno_gpu.h"
 #include "msm_gem.h"
 #include "msm_mmu.h"
@@ -893,6 +894,45 @@ static int adreno_get_pwrlevels(struct device *dev,
 	return 0;
 }
 
+int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
+			  struct adreno_ocmem *adreno_ocmem)
+{
+	struct ocmem_buf *ocmem_hdl;
+	struct ocmem *ocmem;
+
+	ocmem = of_get_ocmem(dev);
+	if (IS_ERR(ocmem)) {
+		if (PTR_ERR(ocmem) == -ENODEV) {
+			/*
+			 * Return success since either the ocmem property was
+			 * not specified in device tree, or ocmem support is
+			 * not compiled into the kernel.
+			 */
+			return 0;
+		}
+
+		return PTR_ERR(ocmem);
+	}
+
+	ocmem_hdl = ocmem_allocate(ocmem, OCMEM_GRAPHICS, adreno_gpu->gmem);
+	if (IS_ERR(ocmem_hdl))
+		return PTR_ERR(ocmem_hdl);
+
+	adreno_ocmem->ocmem = ocmem;
+	adreno_ocmem->base = ocmem_hdl->addr;
+	adreno_ocmem->hdl = ocmem_hdl;
+	adreno_gpu->gmem = ocmem_hdl->len;
+
+	return 0;
+}
+
+void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem)
+{
+	if (adreno_ocmem && adreno_ocmem->base)
+		ocmem_free(adreno_ocmem->ocmem, OCMEM_GRAPHICS,
+			   adreno_ocmem->hdl);
+}
+
 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		struct adreno_gpu *adreno_gpu,
 		const struct adreno_gpu_funcs *funcs, int nr_rings)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index c7441fb8313e..d225a8a92e58 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -126,6 +126,12 @@ struct adreno_gpu {
 };
 #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
 
+struct adreno_ocmem {
+	struct ocmem *ocmem;
+	unsigned long base;
+	void *hdl;
+};
+
 /* platform config data (ie. from DT, or pdata) */
 struct adreno_platform_config {
 	struct adreno_rev rev;
@@ -236,6 +242,10 @@ void adreno_dump(struct msm_gpu *gpu);
 void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords);
 struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu);
 
+int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
+			  struct adreno_ocmem *ocmem);
+void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *ocmem);
+
 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
 		int nr_rings);
commit 88c1e9404f1deee02e52d13aae3d9ee2cabd66f5
Author: Brian Masney <masneyb at onstation.org>
Date:   Fri Aug 23 05:16:35 2019 -0700

    soc: qcom: add OCMEM driver
    
    The OCMEM driver handles allocation and configuration of the On Chip
    MEMory that is present on some Snapdragon SoCs. Devices which have
    OCMEM do not have GMEM inside the GPU core, so the GPU must instead
    use OCMEM to be functional. Since the GPU is currently the only OCMEM
    user with an upstream driver, this is just a minimal implementation
    sufficient for statically allocating to the GPU it's chunk of OCMEM.
    
    This driver currently does not read the gmu-sram node that is described
    in the device tree bindings. The starting memory address of the GPU's
    reserved memory region is hardcoded to zero to match what the hardware
    expects. The driver can be updated to read the reserved memory regions
    from device tree once other users of OCMEM are added upstream.
    
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Co-developed-by: Rob Clark <robdclark at gmail.com>
    Signed-off-by: Rob Clark <robdclark at gmail.com>
    Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
    Tested-by: Gabriel Francisco <frc.gabrielgmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 661e47acc354..adbf3bfae805 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -74,6 +74,16 @@ config QCOM_MDT_LOADER
 	tristate
 	select QCOM_SCM
 
+config QCOM_OCMEM
+	tristate "Qualcomm On Chip Memory (OCMEM) driver"
+	depends on ARCH_QCOM
+	select QCOM_SCM
+	help
+          The On Chip Memory (OCMEM) allocator allows various clients to
+          allocate memory from OCMEM based on performance, latency and power
+          requirements. This is typically used by the GPU, camera/video, and
+          audio components on some Snapdragon SoCs.
+
 config QCOM_PM
 	bool "Qualcomm Power Management"
 	depends on ARCH_QCOM && !ARM64
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 162788701a77..aab333720bfd 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
 obj-$(CONFIG_QCOM_GLINK_SSR) +=	glink_ssr.o
 obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
 obj-$(CONFIG_QCOM_MDT_LOADER)	+= mdt_loader.o
+obj-$(CONFIG_QCOM_OCMEM)	+= ocmem.o
 obj-$(CONFIG_QCOM_PM)	+=	spm.o
 obj-$(CONFIG_QCOM_QMI_HELPERS)	+= qmi_helpers.o
 qmi_helpers-y	+= qmi_encdec.o qmi_interface.o
diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
new file mode 100644
index 000000000000..7f9e9944d1ea
--- /dev/null
+++ b/drivers/soc/qcom/ocmem.c
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * The On Chip Memory (OCMEM) allocator allows various clients to allocate
+ * memory from OCMEM based on performance, latency and power requirements.
+ * This is typically used by the GPU, camera/video, and audio components on
+ * some Snapdragon SoCs.
+ *
+ * Copyright (C) 2019 Brian Masney <masneyb at onstation.org>
+ * Copyright (C) 2015 Red Hat. Author: Rob Clark <robdclark at gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/qcom_scm.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <soc/qcom/ocmem.h>
+
+enum region_mode {
+	WIDE_MODE = 0x0,
+	THIN_MODE,
+	MODE_DEFAULT = WIDE_MODE,
+};
+
+enum ocmem_macro_state {
+	PASSTHROUGH = 0,
+	PERI_ON = 1,
+	CORE_ON = 2,
+	CLK_OFF = 4,
+};
+
+struct ocmem_region {
+	bool interleaved;
+	enum region_mode mode;
+	unsigned int num_macros;
+	enum ocmem_macro_state macro_state[4];
+	unsigned long macro_size;
+	unsigned long region_size;
+};
+
+struct ocmem_config {
+	uint8_t num_regions;
+	unsigned long macro_size;
+};
+
+struct ocmem {
+	struct device *dev;
+	const struct ocmem_config *config;
+	struct resource *memory;
+	void __iomem *mmio;
+	unsigned int num_ports;
+	unsigned int num_macros;
+	bool interleaved;
+	struct ocmem_region *regions;
+	unsigned long active_allocations;
+};
+
+#define OCMEM_MIN_ALIGN				SZ_64K
+#define OCMEM_MIN_ALLOC				SZ_64K
+
+#define OCMEM_REG_HW_VERSION			0x00000000
+#define OCMEM_REG_HW_PROFILE			0x00000004
+
+#define OCMEM_REG_REGION_MODE_CTL		0x00001000
+#define OCMEM_REGION_MODE_CTL_REG0_THIN		0x00000001
+#define OCMEM_REGION_MODE_CTL_REG1_THIN		0x00000002
+#define OCMEM_REGION_MODE_CTL_REG2_THIN		0x00000004
+#define OCMEM_REGION_MODE_CTL_REG3_THIN		0x00000008
+
+#define OCMEM_REG_GFX_MPU_START			0x00001004
+#define OCMEM_REG_GFX_MPU_END			0x00001008
+
+#define OCMEM_HW_PROFILE_NUM_PORTS(val)		FIELD_PREP(0x0000000f, (val))
+#define OCMEM_HW_PROFILE_NUM_MACROS(val)	FIELD_PREP(0x00003f00, (val))
+
+#define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE	0x00010000
+#define OCMEM_HW_PROFILE_INTERLEAVING		0x00020000
+#define OCMEM_REG_GEN_STATUS			0x0000000c
+
+#define OCMEM_REG_PSGSC_STATUS			0x00000038
+#define OCMEM_REG_PSGSC_CTL(i0)			(0x0000003c + 0x1*(i0))
+
+#define OCMEM_PSGSC_CTL_MACRO0_MODE(val)	FIELD_PREP(0x00000007, (val))
+#define OCMEM_PSGSC_CTL_MACRO1_MODE(val)	FIELD_PREP(0x00000070, (val))
+#define OCMEM_PSGSC_CTL_MACRO2_MODE(val)	FIELD_PREP(0x00000700, (val))
+#define OCMEM_PSGSC_CTL_MACRO3_MODE(val)	FIELD_PREP(0x00007000, (val))
+
+#define OCMEM_CLK_CORE_IDX			0
+static struct clk_bulk_data ocmem_clks[] = {
+	{
+		.id = "core",
+	},
+	{
+		.id = "iface",
+	},
+};
+
+static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data)
+{
+	writel(data, ocmem->mmio + reg);
+}
+
+static inline u32 ocmem_read(struct ocmem *ocmem, u32 reg)
+{
+	return readl(ocmem->mmio + reg);
+}
+
+static void update_ocmem(struct ocmem *ocmem)
+{
+	uint32_t region_mode_ctrl = 0x0;
+	int i;
+
+	if (!qcom_scm_ocmem_lock_available()) {
+		for (i = 0; i < ocmem->config->num_regions; i++) {
+			struct ocmem_region *region = &ocmem->regions[i];
+
+			if (region->mode == THIN_MODE)
+				region_mode_ctrl |= BIT(i);
+		}
+
+		dev_dbg(ocmem->dev, "ocmem_region_mode_control %x\n",
+			region_mode_ctrl);
+		ocmem_write(ocmem, OCMEM_REG_REGION_MODE_CTL, region_mode_ctrl);
+	}
+
+	for (i = 0; i < ocmem->config->num_regions; i++) {
+		struct ocmem_region *region = &ocmem->regions[i];
+		u32 data;
+
+		data = OCMEM_PSGSC_CTL_MACRO0_MODE(region->macro_state[0]) |
+			OCMEM_PSGSC_CTL_MACRO1_MODE(region->macro_state[1]) |
+			OCMEM_PSGSC_CTL_MACRO2_MODE(region->macro_state[2]) |
+			OCMEM_PSGSC_CTL_MACRO3_MODE(region->macro_state[3]);
+
+		ocmem_write(ocmem, OCMEM_REG_PSGSC_CTL(i), data);
+	}
+}
+
+static unsigned long phys_to_offset(struct ocmem *ocmem,
+				    unsigned long addr)
+{
+	if (addr < ocmem->memory->start || addr >= ocmem->memory->end)
+		return 0;
+
+	return addr - ocmem->memory->start;
+}
+
+static unsigned long device_address(struct ocmem *ocmem,
+				    enum ocmem_client client,
+				    unsigned long addr)
+{
+	WARN_ON(client != OCMEM_GRAPHICS);
+
+	/* TODO: gpu uses phys_to_offset, but others do not.. */
+	return phys_to_offset(ocmem, addr);
+}
+
+static void update_range(struct ocmem *ocmem, struct ocmem_buf *buf,
+			 enum ocmem_macro_state mstate, enum region_mode rmode)
+{
+	unsigned long offset = 0;
+	int i, j;
+
+	for (i = 0; i < ocmem->config->num_regions; i++) {
+		struct ocmem_region *region = &ocmem->regions[i];
+
+		if (buf->offset <= offset && offset < buf->offset + buf->len)
+			region->mode = rmode;
+
+		for (j = 0; j < region->num_macros; j++) {
+			if (buf->offset <= offset &&
+			    offset < buf->offset + buf->len)
+				region->macro_state[j] = mstate;
+
+			offset += region->macro_size;
+		}
+	}
+
+	update_ocmem(ocmem);
+}
+
+struct ocmem *of_get_ocmem(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *devnode;
+
+	devnode = of_parse_phandle(dev->of_node, "sram", 0);
+	if (!devnode || !devnode->parent) {
+		dev_err(dev, "Cannot look up sram phandle\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	pdev = of_find_device_by_node(devnode->parent);
+	if (!pdev) {
+		dev_err(dev, "Cannot find device node %s\n", devnode->name);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return platform_get_drvdata(pdev);
+}
+EXPORT_SYMBOL(of_get_ocmem);
+
+struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client,
+				 unsigned long size)
+{
+	struct ocmem_buf *buf;
+	int ret;
+
+	/* TODO: add support for other clients... */
+	if (WARN_ON(client != OCMEM_GRAPHICS))
+		return ERR_PTR(-ENODEV);
+
+	if (size < OCMEM_MIN_ALLOC || !IS_ALIGNED(size, OCMEM_MIN_ALIGN))
+		return ERR_PTR(-EINVAL);
+
+	if (test_and_set_bit_lock(BIT(client), &ocmem->active_allocations))
+		return ERR_PTR(-EBUSY);
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto err_unlock;
+	}
+
+	buf->offset = 0;
+	buf->addr = device_address(ocmem, client, buf->offset);
+	buf->len = size;
+
+	update_range(ocmem, buf, CORE_ON, WIDE_MODE);
+
+	if (qcom_scm_ocmem_lock_available()) {
+		ret = qcom_scm_ocmem_lock(QCOM_SCM_OCMEM_GRAPHICS_ID,
+					  buf->offset, buf->len, WIDE_MODE);
+		if (ret) {
+			dev_err(ocmem->dev, "could not lock: %d\n", ret);
+			ret = -EINVAL;
+			goto err_kfree;
+		}
+	} else {
+		ocmem_write(ocmem, OCMEM_REG_GFX_MPU_START, buf->offset);
+		ocmem_write(ocmem, OCMEM_REG_GFX_MPU_END,
+			    buf->offset + buf->len);
+	}
+
+	dev_dbg(ocmem->dev, "using %ldK of OCMEM at 0x%08lx for client %d\n",
+		size / 1024, buf->addr, client);
+
+	return buf;
+
+err_kfree:
+	kfree(buf);
+err_unlock:
+	clear_bit_unlock(BIT(client), &ocmem->active_allocations);
+
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(ocmem_allocate);
+
+void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
+		struct ocmem_buf *buf)
+{
+	/* TODO: add support for other clients... */
+	if (WARN_ON(client != OCMEM_GRAPHICS))
+		return;
+
+	update_range(ocmem, buf, CLK_OFF, MODE_DEFAULT);
+
+	if (qcom_scm_ocmem_lock_available()) {
+		int ret;
+
+		ret = qcom_scm_ocmem_unlock(QCOM_SCM_OCMEM_GRAPHICS_ID,
+					    buf->offset, buf->len);
+		if (ret)
+			dev_err(ocmem->dev, "could not unlock: %d\n", ret);
+	} else {
+		ocmem_write(ocmem, OCMEM_REG_GFX_MPU_START, 0x0);
+		ocmem_write(ocmem, OCMEM_REG_GFX_MPU_END, 0x0);
+	}
+
+	kfree(buf);
+
+	clear_bit_unlock(BIT(client), &ocmem->active_allocations);
+}
+EXPORT_SYMBOL(ocmem_free);
+
+static int ocmem_dev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	unsigned long reg, region_size;
+	int i, j, ret, num_banks;
+	struct resource *res;
+	struct ocmem *ocmem;
+
+	if (!qcom_scm_is_available())
+		return -EPROBE_DEFER;
+
+	ocmem = devm_kzalloc(dev, sizeof(*ocmem), GFP_KERNEL);
+	if (!ocmem)
+		return -ENOMEM;
+
+	ocmem->dev = dev;
+	ocmem->config = device_get_match_data(dev);
+
+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(ocmem_clks), ocmem_clks);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Unable to get clocks\n");
+
+		return ret;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+	ocmem->mmio = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ocmem->mmio)) {
+		dev_err(&pdev->dev, "Failed to ioremap ocmem_ctrl resource\n");
+		return PTR_ERR(ocmem->mmio);
+	}
+
+	ocmem->memory = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						     "mem");
+	if (!ocmem->memory) {
+		dev_err(dev, "Could not get mem region\n");
+		return -ENXIO;
+	}
+
+	/* The core clock is synchronous with graphics */
+	WARN_ON(clk_set_rate(ocmem_clks[OCMEM_CLK_CORE_IDX].clk, 1000) < 0);
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(ocmem_clks), ocmem_clks);
+	if (ret) {
+		dev_info(ocmem->dev, "Failed to enable clocks\n");
+		return ret;
+	}
+
+	if (qcom_scm_restore_sec_cfg_available()) {
+		dev_dbg(dev, "configuring scm\n");
+		ret = qcom_scm_restore_sec_cfg(QCOM_SCM_OCMEM_DEV_ID, 0);
+		if (ret) {
+			dev_err(dev, "Could not enable secure configuration\n");
+			goto err_clk_disable;
+		}
+	}
+
+	reg = ocmem_read(ocmem, OCMEM_REG_HW_PROFILE);
+	ocmem->num_ports = OCMEM_HW_PROFILE_NUM_PORTS(reg);
+	ocmem->num_macros = OCMEM_HW_PROFILE_NUM_MACROS(reg);
+	ocmem->interleaved = !!(reg & OCMEM_HW_PROFILE_INTERLEAVING);
+
+	num_banks = ocmem->num_ports / 2;
+	region_size = ocmem->config->macro_size * num_banks;
+
+	dev_info(dev, "%u ports, %u regions, %u macros, %sinterleaved\n",
+		 ocmem->num_ports, ocmem->config->num_regions,
+		 ocmem->num_macros, ocmem->interleaved ? "" : "not ");
+
+	ocmem->regions = devm_kcalloc(dev, ocmem->config->num_regions,
+				      sizeof(struct ocmem_region), GFP_KERNEL);
+	if (!ocmem->regions) {
+		ret = -ENOMEM;
+		goto err_clk_disable;
+	}
+
+	for (i = 0; i < ocmem->config->num_regions; i++) {
+		struct ocmem_region *region = &ocmem->regions[i];
+
+		if (WARN_ON(num_banks > ARRAY_SIZE(region->macro_state))) {
+			ret = -EINVAL;
+			goto err_clk_disable;
+		}
+
+		region->mode = MODE_DEFAULT;
+		region->num_macros = num_banks;
+
+		if (i == (ocmem->config->num_regions - 1) &&
+		    reg & OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE) {
+			region->macro_size = ocmem->config->macro_size / 2;
+			region->region_size = region_size / 2;
+		} else {
+			region->macro_size = ocmem->config->macro_size;
+			region->region_size = region_size;
+		}
+
+		for (j = 0; j < ARRAY_SIZE(region->macro_state); j++)
+			region->macro_state[j] = CLK_OFF;
+	}
+
+	platform_set_drvdata(pdev, ocmem);
+
+	return 0;
+
+err_clk_disable:
+	clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks);
+	return ret;
+}
+
+static int ocmem_dev_remove(struct platform_device *pdev)
+{
+	clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks);
+
+	return 0;
+}
+
+static const struct ocmem_config ocmem_8974_config = {
+	.num_regions = 3,
+	.macro_size = SZ_128K,
+};
+
+static const struct of_device_id ocmem_of_match[] = {
+	{ .compatible = "qcom,msm8974-ocmem", .data = &ocmem_8974_config },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, ocmem_of_match);
+
+static struct platform_driver ocmem_driver = {
+	.probe = ocmem_dev_probe,
+	.remove = ocmem_dev_remove,
+	.driver = {
+		.name = "ocmem",
+		.of_match_table = ocmem_of_match,
+	},
+};
+
+module_platform_driver(ocmem_driver);
+
+MODULE_DESCRIPTION("On Chip Memory (OCMEM) allocator for some Snapdragon SoCs");
+MODULE_LICENSE("GPL v2");
diff --git a/include/soc/qcom/ocmem.h b/include/soc/qcom/ocmem.h
new file mode 100644
index 000000000000..a0ae336ba78b
--- /dev/null
+++ b/include/soc/qcom/ocmem.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * The On Chip Memory (OCMEM) allocator allows various clients to allocate
+ * memory from OCMEM based on performance, latency and power requirements.
+ * This is typically used by the GPU, camera/video, and audio components on
+ * some Snapdragon SoCs.
+ *
+ * Copyright (C) 2019 Brian Masney <masneyb at onstation.org>
+ * Copyright (C) 2015 Red Hat. Author: Rob Clark <robdclark at gmail.com>
+ */
+
+#ifndef __OCMEM_H__
+#define __OCMEM_H__
+
+enum ocmem_client {
+	/* GMEM clients */
+	OCMEM_GRAPHICS = 0x0,
+	/*
+	 * TODO add more once ocmem_allocate() is clever enough to
+	 * deal with multiple clients.
+	 */
+	OCMEM_CLIENT_MAX,
+};
+
+struct ocmem;
+
+struct ocmem_buf {
+	unsigned long offset;
+	unsigned long addr;
+	unsigned long len;
+};
+
+#if IS_ENABLED(CONFIG_QCOM_OCMEM)
+
+struct ocmem *of_get_ocmem(struct device *dev);
+struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client,
+				 unsigned long size);
+void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
+		struct ocmem_buf *buf);
+
+#else /* IS_ENABLED(CONFIG_QCOM_OCMEM) */
+
+static inline struct ocmem *of_get_ocmem(struct device *dev)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem,
+					       enum ocmem_client client,
+					       unsigned long size)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void ocmem_free(struct ocmem *ocmem, enum ocmem_client client,
+			      struct ocmem_buf *buf)
+{
+}
+
+#endif /* IS_ENABLED(CONFIG_QCOM_OCMEM) */
+
+#endif /* __OCMEM_H__ */
commit 0434a4061471a9afc2b2061add496e58ba4bb92d
Author: Rob Clark <robdclark at gmail.com>
Date:   Fri Aug 23 05:16:34 2019 -0700

    firmware: qcom: scm: add support to restore secure config to qcm_scm-32
    
    Add support to restore the secure configuration for qcm_scm-32.c. This
    is needed by the On Chip MEMory (OCMEM) that is present on some
    Snapdragon devices.
    
    Signed-off-by: Rob Clark <robdclark at gmail.com>
    [masneyb at onstation.org: ported to latest kernel; set ctx_bank_num to
     spare parameter.]
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
    Tested-by: Gabriel Francisco <frc.gabrielgmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 4c2514e5e249..5d90b7f5ab5a 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -617,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
 int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
 			       u32 spare)
 {
-	return -ENODEV;
+	struct msm_scm_sec_cfg {
+		__le32 id;
+		__le32 ctx_bank_num;
+	} cfg;
+	int ret, scm_ret = 0;
+
+	cfg.id = cpu_to_le32(device_id);
+	cfg.ctx_bank_num = cpu_to_le32(spare);
+
+	ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG,
+			    &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret));
+
+	if (ret || scm_ret)
+		return ret ? ret : -EINVAL;
+
+	return 0;
 }
 
 int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 7e285ff3961d..27c1d98a34e6 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -367,6 +367,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = {
 	.deassert = qcom_scm_pas_reset_deassert,
 };
 
+/**
+ * qcom_scm_restore_sec_cfg_available() - Check if secure environment
+ * supports restore security config interface.
+ *
+ * Return true if restore-cfg interface is supported, false if not.
+ */
+bool qcom_scm_restore_sec_cfg_available(void)
+{
+	return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+					    QCOM_SCM_RESTORE_SEC_CFG);
+}
+EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available);
+
 int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)
 {
 	return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare);
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index b49b734d662c..04382e1798e4 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -34,6 +34,16 @@ enum qcom_scm_ocmem_client {
 	QCOM_SCM_OCMEM_DEBUG_ID,
 };
 
+enum qcom_scm_sec_dev_id {
+	QCOM_SCM_MDSS_DEV_ID    = 1,
+	QCOM_SCM_OCMEM_DEV_ID   = 5,
+	QCOM_SCM_PCIE0_DEV_ID   = 11,
+	QCOM_SCM_PCIE1_DEV_ID   = 12,
+	QCOM_SCM_GFX_DEV_ID     = 18,
+	QCOM_SCM_UFS_DEV_ID     = 19,
+	QCOM_SCM_ICE_DEV_ID     = 20,
+};
+
 #define QCOM_SCM_VMID_HLOS       0x3
 #define QCOM_SCM_VMID_MSS_MSA    0xF
 #define QCOM_SCM_VMID_WLAN       0x18
@@ -70,6 +80,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 extern void qcom_scm_cpu_power_down(u32 flags);
 extern u32 qcom_scm_get_version(void);
 extern int qcom_scm_set_remote_state(u32 state, u32 id);
+extern bool qcom_scm_restore_sec_cfg_available(void);
 extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
 extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
 extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
commit b0a1614fb1f58520938968ebe1f4f11bcf34839e
Author: Rob Clark <robdclark at gmail.com>
Date:   Fri Aug 23 05:16:33 2019 -0700

    firmware: qcom: scm: add OCMEM lock/unlock interface
    
    Add support for the OCMEM lock/unlock interface that is needed by the
    On Chip MEMory (OCMEM) that is present on some Snapdragon devices.
    
    Signed-off-by: Rob Clark <robdclark at gmail.com>
    [masneyb at onstation.org: ported to latest kernel; minor reformatting.]
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
    Tested-by: Gabriel Francisco <frc.gabrielgmail.com>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 215061c581e1..4c2514e5e249 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
 		req, req_cnt * sizeof(*req), resp, sizeof(*resp));
 }
 
+int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size,
+			  u32 mode)
+{
+	struct ocmem_tz_lock {
+		__le32 id;
+		__le32 offset;
+		__le32 size;
+		__le32 mode;
+	} request;
+
+	request.id = cpu_to_le32(id);
+	request.offset = cpu_to_le32(offset);
+	request.size = cpu_to_le32(size);
+	request.mode = cpu_to_le32(mode);
+
+	return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD,
+			     &request, sizeof(request), NULL, 0);
+}
+
+int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size)
+{
+	struct ocmem_tz_unlock {
+		__le32 id;
+		__le32 offset;
+		__le32 size;
+	} request;
+
+	request.id = cpu_to_le32(id);
+	request.offset = cpu_to_le32(offset);
+	request.size = cpu_to_le32(size);
+
+	return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD,
+			     &request, sizeof(request), NULL, 0);
+}
+
 void __qcom_scm_init(void)
 {
 }
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index 91d5ad7cf58b..c3a3d9874def 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -241,6 +241,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
 	return ret;
 }
 
+int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset,
+			  uint32_t size, uint32_t mode)
+{
+	return -ENOTSUPP;
+}
+
+int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset,
+			    uint32_t size)
+{
+	return -ENOTSUPP;
+}
+
 void __qcom_scm_init(void)
 {
 	u64 cmd;
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 4802ab170fe5..7e285ff3961d 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -191,6 +191,46 @@ bool qcom_scm_pas_supported(u32 peripheral)
 }
 EXPORT_SYMBOL(qcom_scm_pas_supported);
 
+/**
+ * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
+ */
+bool qcom_scm_ocmem_lock_available(void)
+{
+	return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC,
+					    QCOM_SCM_OCMEM_LOCK_CMD);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_lock_available);
+
+/**
+ * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM
+ * region to the specified initiator
+ *
+ * @id:     tz initiator id
+ * @offset: OCMEM offset
+ * @size:   OCMEM size
+ * @mode:   access mode (WIDE/NARROW)
+ */
+int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size,
+			u32 mode)
+{
+	return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_lock);
+
+/**
+ * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM
+ * region from the specified initiator
+ *
+ * @id:     tz initiator id
+ * @offset: OCMEM offset
+ * @size:   OCMEM size
+ */
+int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size)
+{
+	return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_unlock);
+
 /**
  * qcom_scm_pas_init_image() - Initialize peripheral authentication service
  *			       state machine for a given peripheral, using the
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 99506bd873c0..ef293ee67ec1 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct device *dev,
 
 extern void __qcom_scm_init(void);
 
+#define QCOM_SCM_OCMEM_SVC			0xf
+#define QCOM_SCM_OCMEM_LOCK_CMD		0x1
+#define QCOM_SCM_OCMEM_UNLOCK_CMD		0x2
+
+extern int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset,
+				 u32 size, u32 mode);
+extern int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset,
+				   u32 size);
+
 #define QCOM_SCM_SVC_PIL		0x2
 #define QCOM_SCM_PAS_INIT_IMAGE_CMD	0x1
 #define QCOM_SCM_PAS_MEM_SETUP_CMD	0x2
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index 2d5eff506e13..b49b734d662c 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -24,6 +24,16 @@ struct qcom_scm_vmperm {
 	int perm;
 };
 
+enum qcom_scm_ocmem_client {
+	QCOM_SCM_OCMEM_UNUSED_ID = 0x0,
+	QCOM_SCM_OCMEM_GRAPHICS_ID,
+	QCOM_SCM_OCMEM_VIDEO_ID,
+	QCOM_SCM_OCMEM_LP_AUDIO_ID,
+	QCOM_SCM_OCMEM_SENSORS_ID,
+	QCOM_SCM_OCMEM_OTHER_OS_ID,
+	QCOM_SCM_OCMEM_DEBUG_ID,
+};
+
 #define QCOM_SCM_VMID_HLOS       0x3
 #define QCOM_SCM_VMID_MSS_MSA    0xF
 #define QCOM_SCM_VMID_WLAN       0x18
@@ -41,6 +51,11 @@ extern bool qcom_scm_is_available(void);
 extern bool qcom_scm_hdcp_available(void);
 extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
 			     u32 *resp);
+extern bool qcom_scm_ocmem_lock_available(void);
+extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
+			       u32 size, u32 mode);
+extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset,
+				 u32 size);
 extern bool qcom_scm_pas_supported(u32 peripheral);
 extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
 				   size_t size);
commit 198a72c8f9ee8eef24bacde6a3b3feb3b026ee04
Author: Brian Masney <masneyb at onstation.org>
Date:   Fri Aug 23 05:16:32 2019 -0700

    dt-bindings: display: msm: gmu: add optional ocmem property
    
    Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and
    must use the On Chip MEMory (OCMEM) in order to be functional. Add the
    optional ocmem property to the Adreno Graphics Management Unit bindings.
    
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reviewed-by: Rob Herring <robh at kernel.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt
index 90af5b0a56a9..bf9c7a2a495c 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.txt
+++ b/Documentation/devicetree/bindings/display/msm/gmu.txt
@@ -31,6 +31,10 @@ Required properties:
 - iommus: phandle to the adreno iommu
 - operating-points-v2: phandle to the OPP operating points
 
+Optional properties:
+- sram: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon
+        SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml.
+
 Example:
 
 / {
@@ -63,3 +67,50 @@ Example:
 		operating-points-v2 = <&gmu_opp_table>;
 	};
 };
+
+a3xx example with OCMEM support:
+
+/ {
+	...
+
+	gpu: adreno at fdb00000 {
+		compatible = "qcom,adreno-330.2",
+		             "qcom,adreno";
+		reg = <0xfdb00000 0x10000>;
+		reg-names = "kgsl_3d0_reg_memory";
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_3d0_irq";
+		clock-names = "core",
+		              "iface",
+		              "mem_iface";
+		clocks = <&mmcc OXILI_GFX3D_CLK>,
+		         <&mmcc OXILICX_AHB_CLK>,
+		         <&mmcc OXILICX_AXI_CLK>;
+		sram = <&gmu_sram>;
+		power-domains = <&mmcc OXILICX_GDSC>;
+		operating-points-v2 = <&gpu_opp_table>;
+		iommus = <&gpu_iommu 0>;
+	};
+
+	ocmem at fdd00000 {
+		compatible = "qcom,msm8974-ocmem";
+
+		reg = <0xfdd00000 0x2000>,
+		      <0xfec00000 0x180000>;
+		reg-names = "ctrl",
+		             "mem";
+
+		clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+		         <&mmcc OCMEMCX_OCMEMNOC_CLK>;
+		clock-names = "core",
+		              "iface";
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		gmu_sram: gmu-sram at 0 {
+			reg = <0x0 0x100000>;
+			ranges = <0 0 0xfec00000 0x100000>;
+		};
+	};
+};
commit 957fd69d396b2cc9b74c3b31a70fe7f266aa8c16
Author: Brian Masney <masneyb at onstation.org>
Date:   Fri Aug 23 05:16:31 2019 -0700

    dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings
    
    Add device tree bindings for the On Chip Memory (OCMEM) that is present
    on some Qualcomm Snapdragon SoCs.
    
    Signed-off-by: Brian Masney <masneyb at onstation.org>
    Reviewed-by: Rob Herring <robh at kernel.org>
    Signed-off-by: Rob Clark <robdclark at chromium.org>

diff --git a/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml
new file mode 100644
index 000000000000..222990f9923c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sram/qcom,ocmem.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs.
+
+maintainers:
+  - Brian Masney <masneyb at onstation.org>
+
+description: |
+  The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and
+  audio components on some Snapdragon SoCs.
+
+properties:
+  compatible:
+    const: qcom,msm8974-ocmem
+
+  reg:
+    items:
+      - description: Control registers
+      - description: OCMEM address range
+
+  reg-names:
+    items:
+      - const: ctrl
+      - const: mem
+
+  clocks:
+    items:
+      - description: Core clock
+      - description: Interface clock
+
+  clock-names:
+    items:
+      - const: core
+      - const: iface
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+patternProperties:
+  "^.+-sram$":
+    type: object
+    description: A region of reserved memory.
+
+    properties:
+      reg:
+        maxItems: 1
+
+      ranges:
+        maxItems: 1
+
+    required:
+      - reg
+      - ranges
+
+examples:
+  - |
+      #include <dt-bindings/clock/qcom,rpmcc.h>
+      #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
+
+      ocmem: ocmem at fdd00000 {
+        compatible = "qcom,msm8974-ocmem";
+
+        reg = <0xfdd00000 0x2000>,
+              <0xfec00000 0x180000>;
+        reg-names = "ctrl",
+                    "mem";
+
+        clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+                 <&mmcc OCMEMCX_OCMEMNOC_CLK>;
+        clock-names = "core",
+                      "iface";
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        gmu-sram at 0 {
+                reg = <0x0 0x100000>;
+                ranges = <0 0 0xfec00000 0x100000>;
+        };
+      };


More information about the openchrome-devel mailing list