[PATCH] drm/amdgpu: fix build error without CONFIG_HSA_AMD

2019-09-10 Thread S, Shirish
If CONFIG_HSA_AMD is not set, build fails:

drivers/gpu/drm/amd/amdgpu/amdgpu_device.o: In function 
`amdgpu_device_ip_early_init':
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1626: undefined reference to 
`sched_policy'

Use CONFIG_HSA_AMD to guard this.

Fixes: 1abb680ad371 ("drm/amdgpu: disable gfxoff while use no H/W scheduling 
policy")

Signed-off-by: Shirish S 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h| 2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 1030cb30720c..a1516a3ae9a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -169,7 +169,9 @@ extern int amdgpu_discovery;
 extern int amdgpu_mes;
 extern int amdgpu_noretry;
 extern int amdgpu_force_asic_type;
+#ifdef CONFIG_HSA_AMD
 extern int sched_policy;
+#endif
 
 #ifdef CONFIG_DRM_AMDGPU_SI
 extern int amdgpu_si_support;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index bd423dd64e18..2535db27f821 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1623,7 +1623,11 @@ static int amdgpu_device_ip_early_init(struct 
amdgpu_device *adev)
}
 
adev->pm.pp_feature = amdgpu_pp_feature_mask;
-   if (amdgpu_sriov_vf(adev) || sched_policy == KFD_SCHED_POLICY_NO_HWS)
+   if (amdgpu_sriov_vf(adev)
+   #ifdef CONFIG_HSA_AMD
+   || sched_policy == KFD_SCHED_POLICY_NO_HWS
+   #endif
+   )
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
 
for (i = 0; i < adev->num_ip_blocks; i++) {
-- 
2.20.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdgpu/sriov: add ring_stop before ring_create in psp v11 code

2019-09-10 Thread Jack Zhang
psp  v11 code missed ring stop in ring create function(VMR)
while psp v3.1 code had the code. This will cause VM destroy1
fail and psp ring create fail.

For SIOV-VF, ring_stop should not be deleted in ring_create
function.

Signed-off-by: Jack Zhang 
---
 drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 61 +++---
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
index cddfa3c..8e9b34a 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
@@ -397,6 +397,34 @@ static bool psp_v11_0_support_vmr_ring(struct psp_context 
*psp)
return false;
 }
 
+static int psp_v11_0_ring_stop(struct psp_context *psp,
+ enum psp_ring_type ring_type)
+{
+   int ret = 0;
+   struct amdgpu_device *adev = psp->adev;
+
+   /* Write the ring destroy command*/
+   if (psp_v11_0_support_vmr_ring(psp))
+   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
+GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
+   else
+   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
+GFX_CTRL_CMD_ID_DESTROY_RINGS);
+
+   /* there might be handshake issue with hardware which needs delay */
+   mdelay(20);
+
+   /* Wait for response flag (bit 31) */
+   if (psp_v11_0_support_vmr_ring(psp))
+   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_101),
+  0x8000, 0x8000, false);
+   else
+   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_64),
+  0x8000, 0x8000, false);
+
+   return ret;
+}
+
 static int psp_v11_0_ring_create(struct psp_context *psp,
enum psp_ring_type ring_type)
 {
@@ -406,6 +434,12 @@ static int psp_v11_0_ring_create(struct psp_context *psp,
struct amdgpu_device *adev = psp->adev;
 
if (psp_v11_0_support_vmr_ring(psp)) {
+   ret = psp_v11_0_ring_stop(psp, ring_type);
+   if (ret) {
+   DRM_ERROR("psp_v11_0_ring_stop_sriov failed!\n");
+   return ret;
+   }
+
/* Write low address of the ring to C2PMSG_102 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg);
@@ -450,33 +484,6 @@ static int psp_v11_0_ring_create(struct psp_context *psp,
return ret;
 }
 
-static int psp_v11_0_ring_stop(struct psp_context *psp,
- enum psp_ring_type ring_type)
-{
-   int ret = 0;
-   struct amdgpu_device *adev = psp->adev;
-
-   /* Write the ring destroy command*/
-   if (psp_v11_0_support_vmr_ring(psp))
-   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
-GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
-   else
-   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
-GFX_CTRL_CMD_ID_DESTROY_RINGS);
-
-   /* there might be handshake issue with hardware which needs delay */
-   mdelay(20);
-
-   /* Wait for response flag (bit 31) */
-   if (psp_v11_0_support_vmr_ring(psp))
-   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_101),
-  0x8000, 0x8000, false);
-   else
-   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_64),
-  0x8000, 0x8000, false);
-
-   return ret;
-}
 
 static int psp_v11_0_ring_destroy(struct psp_context *psp,
 enum psp_ring_type ring_type)
-- 
2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

RE: [PATCH] drm/amdgpu: fix build error without CONFIG_HSA_AMD

2019-09-10 Thread Huang, Ray
> -Original Message-
> From: S, Shirish 
> Sent: Tuesday, September 10, 2019 3:54 PM
> To: Deucher, Alexander ; Koenig, Christian
> ; Huang, Ray 
> Cc: amd-gfx@lists.freedesktop.org; S, Shirish 
> Subject: [PATCH] drm/amdgpu: fix build error without CONFIG_HSA_AMD
> 
> If CONFIG_HSA_AMD is not set, build fails:
> 
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.o: In function
> `amdgpu_device_ip_early_init':
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1626: undefined
> reference to `sched_policy'
> 
> Use CONFIG_HSA_AMD to guard this.
> 
> Fixes: 1abb680ad371 ("drm/amdgpu: disable gfxoff while use no H/W
> scheduling policy")
> 
> Signed-off-by: Shirish S 

+ Felix for his awareness.

Reviewed-by: Huang Rui 

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h| 2 ++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +-
>  2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 1030cb30720c..a1516a3ae9a8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -169,7 +169,9 @@ extern int amdgpu_discovery;  extern int
> amdgpu_mes;  extern int amdgpu_noretry;  extern int
> amdgpu_force_asic_type;
> +#ifdef CONFIG_HSA_AMD
>  extern int sched_policy;
> +#endif
> 
>  #ifdef CONFIG_DRM_AMDGPU_SI
>  extern int amdgpu_si_support;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index bd423dd64e18..2535db27f821 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1623,7 +1623,11 @@ static int amdgpu_device_ip_early_init(struct
> amdgpu_device *adev)
>   }
> 
>   adev->pm.pp_feature = amdgpu_pp_feature_mask;
> - if (amdgpu_sriov_vf(adev) || sched_policy ==
> KFD_SCHED_POLICY_NO_HWS)
> + if (amdgpu_sriov_vf(adev)
> + #ifdef CONFIG_HSA_AMD
> + || sched_policy == KFD_SCHED_POLICY_NO_HWS
> + #endif
> + )
>   adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
> 
>   for (i = 0; i < adev->num_ip_blocks; i++) {
> --
> 2.20.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 1/3] drm/amdgpu: move umc late init from gmc to umc block

2019-09-10 Thread Christian König

Am 10.09.19 um 08:31 schrieb Zhou1, Tao:

umc late init is umc specific, it's more suitable to be put in umc block

Signed-off-by: Tao Zhou 


Maybe rename amdgpu_ras.h into amdgpu_umc.h then, but apart from that 
Acked-by: Christian König  for this patch.



---
  drivers/gpu/drm/amd/amdgpu/Makefile |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 48 
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  2 -
  drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c | 73 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h |  2 +
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   |  8 ++-
  drivers/gpu/drm/amd/amdgpu/umc_v6_1.c   |  1 +
  7 files changed, 82 insertions(+), 54 deletions(-)
  create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c

diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index 84614a71bb4d..91369c823ce2 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -55,7 +55,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \
amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o 
amdgpu_vm_cpu.o \
amdgpu_vm_sdma.o amdgpu_pmu.o amdgpu_discovery.o amdgpu_ras_eeprom.o 
amdgpu_nbio.o \
-   smu_v11_0_i2c.o
+   amdgpu_umc.o smu_v11_0_i2c.o
  
  amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
  
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c

index 51890b1d8522..dc044eec188e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -304,51 +304,3 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, 
uint64_t addr,
gmc->fault_hash[hash].idx = gmc->last_fault++;
return false;
  }
-
-int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev,
-void *ras_ih_info)
-{
-   int r;
-   struct ras_ih_if *ih_info = (struct ras_ih_if *)ras_ih_info;
-   struct ras_fs_if fs_info = {
-   .sysfs_name = "umc_err_count",
-   .debugfs_name = "umc_err_inject",
-   };
-
-   if (!ih_info)
-   return -EINVAL;
-
-   if (!adev->gmc.umc_ras_if) {
-   adev->gmc.umc_ras_if = kmalloc(sizeof(struct ras_common_if), 
GFP_KERNEL);
-   if (!adev->gmc.umc_ras_if)
-   return -ENOMEM;
-   adev->gmc.umc_ras_if->block = AMDGPU_RAS_BLOCK__UMC;
-   adev->gmc.umc_ras_if->type = 
AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
-   adev->gmc.umc_ras_if->sub_block_index = 0;
-   strcpy(adev->gmc.umc_ras_if->name, "umc");
-   }
-   ih_info->head = fs_info.head = *adev->gmc.umc_ras_if;
-
-   r = amdgpu_ras_late_init(adev, adev->gmc.umc_ras_if,
-&fs_info, ih_info);
-   if (r)
-   goto free;
-
-   if (amdgpu_ras_is_supported(adev, adev->gmc.umc_ras_if->block)) {
-   r = amdgpu_irq_get(adev, &adev->gmc.ecc_irq, 0);
-   if (r)
-   goto late_fini;
-   } else {
-   r = 0;
-   goto free;
-   }
-
-   return 0;
-
-late_fini:
-   amdgpu_ras_late_fini(adev, adev->gmc.umc_ras_if, ih_info);
-free:
-   kfree(adev->gmc.umc_ras_if);
-   adev->gmc.umc_ras_if = NULL;
-   return r;
-}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index 232a8ff5642b..d3be51ba6349 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -234,7 +234,5 @@ void amdgpu_gmc_agp_location(struct amdgpu_device *adev,
 struct amdgpu_gmc *mc);
  bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, uint64_t addr,
  uint16_t pasid, uint64_t timestamp);
-int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev,
-void *ih_info);
  
  #endif

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
new file mode 100644
index ..c8de127097ab
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPL

[PATCH] drm/amdgpu: remove duplicated header file include

2019-09-10 Thread Chen, Guchun
amdgpu_ras.h is already included.

Fixes: b1718da (dmr/amdgpu: Avoid HW GPU reset for RAS.)

Change-Id: I4cf1eb5393d80c42b426dc1ddfc696e486a02c6f
Signed-off-by: Guchun Chen 
---
 drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c 
b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
index bfa919190fb4..2d171bf07ad5 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
@@ -30,7 +30,6 @@
 #include "nbio/nbio_7_4_0_smn.h"
 #include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
 #include 
-#include "amdgpu_ras.h"
 
 #define smnNBIF_MGCG_CTRL_LCLK 0x1013a21c
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/radeon: Bail earlier when radeon.cik_/si_support=0 is passed

2019-09-10 Thread Michel Dänzer
On 2019-09-07 10:32 p.m., Hans de Goede wrote:
> Bail from the pci_driver probe function instead of from the drm_driver
> load function.
> 
> This avoid /dev/dri/card0 temporarily getting registered and then
> unregistered again, sending unwanted add / remove udev events to
> userspace.
> 
> Specifically this avoids triggering the (userspace) bug fixed by this
> plymouth merge-request:
> https://gitlab.freedesktop.org/plymouth/plymouth/merge_requests/59
> 
> Note that despite that being an userspace bug, not sending unnecessary
> udev events is a good idea in general.
> 
> BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1490490
> Signed-off-by: Hans de Goede 

Reviewed-by: Michel Dänzer 


amdgpu should be changed correspondingly as well.


-- 
Earthling Michel Dänzer   |   https://redhat.com
Libre software enthusiast | Mesa and X developer
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: grab the id mgr lock while accessing passid_mapping

2019-09-10 Thread Christian König

Ping!

Am 09.09.19 um 13:59 schrieb Christian König:

Need to make sure that we actually dropping the right fence.
Could be done with RCU as well, but to complicated for a fix.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index b285ab25146d..e11764164cbf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1036,10 +1036,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct 
amdgpu_job *job, bool need_
id->oa_base != job->oa_base ||
id->oa_size != job->oa_size);
bool vm_flush_needed = job->vm_needs_flush;
-   bool pasid_mapping_needed = id->pasid != job->pasid ||
-   !id->pasid_mapping ||
-   !dma_fence_is_signaled(id->pasid_mapping);
struct dma_fence *fence = NULL;
+   bool pasid_mapping_needed;
unsigned patch_offset = 0;
int r;
  
@@ -1049,6 +1047,12 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_

pasid_mapping_needed = true;
}
  
+	mutex_lock(&id_mgr->lock);

+   if (id->pasid != job->pasid || !id->pasid_mapping ||
+   !dma_fence_is_signaled(id->pasid_mapping))
+   pasid_mapping_needed = true;
+   mutex_unlock(&id_mgr->lock);
+
gds_switch_needed &= !!ring->funcs->emit_gds_switch;
vm_flush_needed &= !!ring->funcs->emit_vm_flush  &&
job->vm_pd_addr != AMDGPU_BO_INVALID_OFFSET;
@@ -1088,9 +1092,11 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct 
amdgpu_job *job, bool need_
}
  
  	if (pasid_mapping_needed) {

+   mutex_lock(&id_mgr->lock);
id->pasid = job->pasid;
dma_fence_put(id->pasid_mapping);
id->pasid_mapping = dma_fence_get(fence);
+   mutex_unlock(&id_mgr->lock);
}
dma_fence_put(fence);
  


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[Patch] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10

2019-09-10 Thread Yin, Tianci (Rico)

From 3bd277d5c954d1bbcbb0ebec28216c3f23ce8e7d Mon Sep 17 00:00:00 2001
From: "Tianci.Yin" 
Date: Tue, 10 Sep 2019 16:54:14 +0800
Subject: [PATCH] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10

add and_mask since the programming logic of golden setting changed

Change-Id: If3744beb779c56255c7e797eb115bd6e462237c5
Signed-off-by: Tianci.Yin 
---
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 90348fb29..b75ef89 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -513,9 +513,9 @@ static const struct soc15_reg_golden golden_settings_gc_9_0[] =
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0x, 0xb5d3f197),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x1920),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x0fff, 0x03ff),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x, 0x0800),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x, 0x0800),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x, 0x8000)
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x0800, 0x0800),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x0800, 0x0800),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x8000, 0x8000)
 };
 
 static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
@@ -578,9 +578,9 @@ static const struct soc15_reg_golden golden_settings_gc_9_1[] =
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x1920),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x0fff, 0x00ff),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x0800, 0x0880),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x, 0x0800),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x, 0x0800),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x, 0x8000)
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x0800, 0x0800),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x0800, 0x0800),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x8000, 0x8000)
 };
 
 static const struct soc15_reg_golden golden_settings_gc_9_1_rv1[] =
@@ -672,9 +672,9 @@ static const struct soc15_reg_golden golden_settings_gc_9_2_1_vg12[] =
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0x, 0x),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0x, 0x76325410),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01bd9f33, 0x0100),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x, 0x0800),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x, 0x0800),
-	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x, 0x8000)
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x0800, 0x0800),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x0800, 0x0800),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x8000, 0x8000)
 };
 
 static const struct soc15_reg_golden golden_settings_gc_9_4_1_arct[] =
-- 
2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH v2 07/27] drm/dp_mst: Add sideband down request tracing + selftests

2019-09-10 Thread Jani Nikula
On Tue, 03 Sep 2019, Lyude Paul  wrote:
> Unfortunately the DP MST helpers do not have much in the way of
> debugging utilities. So, let's add some!
>
> This adds basic debugging output for down sideband requests that we send
> from the driver, so that we can actually discern what's happening when
> sideband requests timeout.
>
> Since there wasn't really a good way of testing that any of this worked,
> I ended up writing simple selftests that lightly test sideband message
> encoding and decoding as well. Enjoy!
>
> Changes since v1:
> * Clean up DO_TEST() and sideband_msg_req_encode_decode() - danvet
> * Get rid of pr_fmt(), just define a prefix string instead and use
>   drm_printf()
> * Check highest bit of VCPI in drm_dp_decode_sideband_req() - danvet
> * Make the switch case order between drm_dp_decode_sideband_req() and
>   drm_dp_encode_sideband_req() the same - danvet
> * Only check DRM_UT_DP - danvet
> * Clean up sideband_msg_req_equal() from selftests a bit, and add
>   comments explaining why we can't just use memcmp - danvet
>
> Cc: Juston Li 
> Cc: Imre Deak 
> Cc: Ville Syrjälä 
> Cc: Harry Wentland 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 309 +-
>  .../gpu/drm/drm_dp_mst_topology_internal.h|  24 ++
>  .../gpu/drm/selftests/drm_modeset_selftests.h |   1 +
>  .../drm/selftests/test-drm_dp_mst_helper.c| 204 
>  .../drm/selftests/test-drm_modeset_common.h   |   1 +
>  include/drm/drm_dp_mst_helper.h   |   2 +-
>  6 files changed, 536 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_dp_mst_topology_internal.h
>
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 1c862749cb63..f5f1d8b50fb6 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -37,6 +37,7 @@
>  #include 
>  
>  #include "drm_crtc_helper_internal.h"
> +#include "drm_dp_mst_topology_internal.h"
>  
>  /**
>   * DOC: dp mst helper
> @@ -73,6 +74,8 @@ static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux 
> *aux);
>  static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
>  static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);
>  
> +#define DBG_PREFIX "[dp_mst]"
> +
>  #define DP_STR(x) [DP_ ## x] = #x
>  
>  static const char *drm_dp_mst_req_type_str(u8 req_type)
> @@ -129,6 +132,43 @@ static const char *drm_dp_mst_nak_reason_str(u8 
> nak_reason)
>  }
>  
>  #undef DP_STR
> +#define DP_STR(x) [DRM_DP_SIDEBAND_TX_ ## x] = #x
> +
> +static const char *drm_dp_mst_sideband_tx_state_str(int state)
> +{
> + static const char * const sideband_reason_str[] = {
> + DP_STR(QUEUED),
> + DP_STR(START_SEND),
> + DP_STR(SENT),
> + DP_STR(RX),
> + DP_STR(TIMEOUT),
> + };
> +
> + if (state >= ARRAY_SIZE(sideband_reason_str) ||
> + !sideband_reason_str[state])
> + return "unknown";
> +
> + return sideband_reason_str[state];
> +}
> +
> +static int
> +drm_dp_mst_rad_to_str(const u8 rad[8], u8 lct, char *out, size_t len)
> +{
> + int i;
> + u8 unpacked_rad[16];
> +
> + for (i = 0; i < lct; i++) {
> + if (i % 2)
> + unpacked_rad[i] = rad[i / 2] >> 4;
> + else
> + unpacked_rad[i] = rad[i / 2] & BIT_MASK(4);
> + }
> +
> + /* TODO: Eventually add something to printk so we can format the rad
> +  * like this: 1.2.3
> +  */
> + return snprintf(out, len, "%*phC", lct, unpacked_rad);
> +}
>  
>  /* sideband msg handling */
>  static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t num_nibbles)
> @@ -261,8 +301,9 @@ static bool drm_dp_decode_sideband_msg_hdr(struct 
> drm_dp_sideband_msg_hdr *hdr,
>   return true;
>  }
>  
> -static void drm_dp_encode_sideband_req(struct drm_dp_sideband_msg_req_body 
> *req,
> -struct drm_dp_sideband_msg_tx *raw)
> +void
> +drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> +struct drm_dp_sideband_msg_tx *raw)
>  {
>   int idx = 0;
>   int i;
> @@ -363,6 +404,251 @@ static void drm_dp_encode_sideband_req(struct 
> drm_dp_sideband_msg_req_body *req,
>   }
>   raw->cur_len = idx;
>  }
> +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_encode_sideband_req);
> +
> +/* Decode a sideband request we've encoded, mainly used for debugging */
> +int
> +drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> +struct drm_dp_sideband_msg_req_body *req)
> +{
> + const u8 *buf = raw->msg;
> + int i, idx = 0;
> +
> + req->req_type = buf[idx++] & 0x7f;
> + switch (req->req_type) {
> + case DP_ENUM_PATH_RESOURCES:
> + case DP_POWER_DOWN_PHY:
> + case DP_POWER_UP_PHY:
> + req->u.port_num.port_number = (buf[idx

RE: [PATCH] drm/amdgpu: remove duplicated header file include

2019-09-10 Thread Zhou1, Tao
Reviewed-by: Tao Zhou 

> -Original Message-
> From: Chen, Guchun 
> Sent: 2019年9月10日 16:44
> To: amd-gfx@lists.freedesktop.org; Zhang, Hawking
> ; Zhou1, Tao ;
> Grodzovsky, Andrey 
> Cc: Chen, Guchun 
> Subject: [PATCH] drm/amdgpu: remove duplicated header file include
> 
> amdgpu_ras.h is already included.
> 
> Fixes: b1718da (dmr/amdgpu: Avoid HW GPU reset for RAS.)
> 
> Change-Id: I4cf1eb5393d80c42b426dc1ddfc696e486a02c6f
> Signed-off-by: Guchun Chen 
> ---
>  drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> index bfa919190fb4..2d171bf07ad5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> @@ -30,7 +30,6 @@
>  #include "nbio/nbio_7_4_0_smn.h"
>  #include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
>  #include 
> -#include "amdgpu_ras.h"
> 
>  #define smnNBIF_MGCG_CTRL_LCLK   0x1013a21c
> 
> --
> 2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 3/9] drm/amdgpu: allow direct submission in the VM backends v2

2019-09-10 Thread Christian König
This allows us to update page tables directly while in a page fault.

v2: use direct/delayed entities and still wait for moves

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  5 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c  | 16 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 25 +++--
 3 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 7138722ee55f..54dcd0bcce1a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -201,6 +201,11 @@ struct amdgpu_vm_update_params {
 */
struct amdgpu_vm *vm;
 
+   /**
+* @direct: if changes should be made directly
+*/
+   bool direct;
+
/**
 * @pages_addr:
 *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
index 5222d165abfc..a2daeadd770f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
@@ -49,13 +49,6 @@ static int amdgpu_vm_cpu_prepare(struct 
amdgpu_vm_update_params *p, void *owner,
 {
int r;
 
-   /* Wait for PT BOs to be idle. PTs share the same resv. object
-* as the root PD BO
-*/
-   r = amdgpu_bo_sync_wait(p->vm->root.base.bo, owner, true);
-   if (unlikely(r))
-   return r;
-
/* Wait for any BO move to be completed */
if (exclusive) {
r = dma_fence_wait(exclusive, true);
@@ -63,7 +56,14 @@ static int amdgpu_vm_cpu_prepare(struct 
amdgpu_vm_update_params *p, void *owner,
return r;
}
 
-   return 0;
+   /* Don't wait for submissions during page fault */
+   if (p->direct)
+   return 0;
+
+   /* Wait for PT BOs to be idle. PTs share the same resv. object
+* as the root PD BO
+*/
+   return amdgpu_bo_sync_wait(p->vm->root.base.bo, owner, true);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index d087d6650d79..38c966cedc26 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -68,17 +68,19 @@ static int amdgpu_vm_sdma_prepare(struct 
amdgpu_vm_update_params *p,
if (r)
return r;
 
+   p->num_dw_left = ndw;
+
+   /* Wait for moves to be completed */
r = amdgpu_sync_fence(p->adev, &p->job->sync, exclusive, false);
if (r)
return r;
 
-   r = amdgpu_sync_resv(p->adev, &p->job->sync, root->tbo.resv,
-owner, false);
-   if (r)
-   return r;
+   /* Don't wait for any submissions during page fault handling */
+   if (p->direct)
+   return 0;
 
-   p->num_dw_left = ndw;
-   return 0;
+   return amdgpu_sync_resv(p->adev, &p->job->sync, root->tbo.resv,
+   owner, false);
 }
 
 /**
@@ -95,23 +97,23 @@ static int amdgpu_vm_sdma_commit(struct 
amdgpu_vm_update_params *p,
 {
struct amdgpu_bo *root = p->vm->root.base.bo;
struct amdgpu_ib *ib = p->job->ibs;
+   struct drm_sched_entity *entity;
struct amdgpu_ring *ring;
struct dma_fence *f;
int r;
 
-   ring = container_of(p->vm->delayed.rq->sched, struct amdgpu_ring,
-   sched);
+   entity = p->direct ? &p->vm->direct : &p->vm->delayed;
+   ring = container_of(entity->rq->sched, struct amdgpu_ring, sched);
 
WARN_ON(ib->length_dw == 0);
amdgpu_ring_pad_ib(ring, ib);
WARN_ON(ib->length_dw > p->num_dw_left);
-   r = amdgpu_job_submit(p->job, &p->vm->delayed,
- AMDGPU_FENCE_OWNER_VM, &f);
+   r = amdgpu_job_submit(p->job, entity, AMDGPU_FENCE_OWNER_VM, &f);
if (r)
goto error;
 
amdgpu_bo_fence(root, f, true);
-   if (fence)
+   if (fence && !p->direct)
swap(*fence, f);
dma_fence_put(f);
return 0;
@@ -121,7 +123,6 @@ static int amdgpu_vm_sdma_commit(struct 
amdgpu_vm_update_params *p,
return r;
 }
 
-
 /**
  * amdgpu_vm_sdma_copy_ptes - copy the PTEs from mapping
  *
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 7/9] drm/amdgpu: allocate PDs/PTs with no_gpu_wait in a page fault

2019-09-10 Thread Christian König
While handling a page fault we can't wait for other ongoing GPU
operations or we can potentially run into deadlocks.

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 8 +---
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 04767905f004..510d04fd6e5f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -451,7 +451,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
 {
struct ttm_operation_ctx ctx = {
.interruptible = (bp->type != ttm_bo_type_kernel),
-   .no_wait_gpu = false,
+   .no_wait_gpu = bp->no_wait_gpu,
.resv = bp->resv,
.flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 5a3c1779e200..e6ddd048a984 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -41,6 +41,7 @@ struct amdgpu_bo_param {
u32 preferred_domain;
u64 flags;
enum ttm_bo_typetype;
+   boolno_wait_gpu;
struct reservation_object   *resv;
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6c94c5a562cf..3b954b53a450 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -821,7 +821,8 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
  * @bp: resulting BO allocation parameters
  */
 static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm 
*vm,
-  int level, struct amdgpu_bo_param *bp)
+  int level, bool direct,
+  struct amdgpu_bo_param *bp)
 {
memset(bp, 0, sizeof(*bp));
 
@@ -836,6 +837,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
else if (!vm->root.base.bo || vm->root.base.bo->shadow)
bp->flags |= AMDGPU_GEM_CREATE_SHADOW;
bp->type = ttm_bo_type_kernel;
+   bp->no_wait_gpu = direct;
if (vm->root.base.bo)
bp->resv = vm->root.base.bo->tbo.resv;
 }
@@ -877,7 +879,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
if (entry->base.bo)
return 0;
 
-   amdgpu_vm_bo_param(adev, vm, cursor->level, &bp);
+   amdgpu_vm_bo_param(adev, vm, cursor->level, direct, &bp);
 
r = amdgpu_bo_create(adev, &bp, &pt);
if (r)
@@ -2713,7 +2715,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
vm->update_funcs = &amdgpu_vm_sdma_funcs;
vm->last_update = NULL;
 
-   amdgpu_vm_bo_param(adev, vm, adev->vm_manager.root_level, &bp);
+   amdgpu_vm_bo_param(adev, vm, adev->vm_manager.root_level, false, &bp);
if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE)
bp.flags &= ~AMDGPU_GEM_CREATE_SHADOW;
r = amdgpu_bo_create(adev, &bp, &root);
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 1/9] drm/ttm: return -EBUSY on pipelining with no_gpu_wait

2019-09-10 Thread Christian König
Setting the no_gpu_wait flag means that the allocate BO must be available
immediately and we can't wait for any GPU operation to finish.

Signed-off-by: Christian König 
Acked-by: Felix Kuehling 
---
 drivers/gpu/drm/ttm/ttm_bo.c | 43 +---
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 2070e8a57ed8..2899702139fb 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -924,7 +924,8 @@ EXPORT_SYMBOL(ttm_bo_mem_put);
  */
 static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
 struct ttm_mem_type_manager *man,
-struct ttm_mem_reg *mem)
+struct ttm_mem_reg *mem,
+bool no_wait_gpu)
 {
struct dma_fence *fence;
int ret;
@@ -933,19 +934,22 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object 
*bo,
fence = dma_fence_get(man->move);
spin_unlock(&man->move_lock);
 
-   if (fence) {
-   reservation_object_add_shared_fence(bo->resv, fence);
+   if (!fence)
+   return 0;
 
-   ret = reservation_object_reserve_shared(bo->resv, 1);
-   if (unlikely(ret)) {
-   dma_fence_put(fence);
-   return ret;
-   }
+   if (no_wait_gpu)
+   return -EBUSY;
+
+   reservation_object_add_shared_fence(bo->resv, fence);
 
-   dma_fence_put(bo->moving);
-   bo->moving = fence;
+   ret = reservation_object_reserve_shared(bo->resv, 1);
+   if (unlikely(ret)) {
+   dma_fence_put(fence);
+   return ret;
}
 
+   dma_fence_put(bo->moving);
+   bo->moving = fence;
return 0;
 }
 
@@ -974,7 +978,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object 
*bo,
return ret;
} while (1);
 
-   return ttm_bo_add_move_fence(bo, man, mem);
+   return ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);
 }
 
 static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man,
@@ -1116,13 +1120,16 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
if (unlikely(ret))
goto error;
 
-   if (mem->mm_node) {
-   ret = ttm_bo_add_move_fence(bo, man, mem);
-   if (unlikely(ret)) {
-   (*man->func->put_node)(man, mem);
-   goto error;
-   }
-   return 0;
+   if (!mem->mm_node)
+   continue;
+
+   ret = ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);
+   if (unlikely(ret)) {
+   (*man->func->put_node)(man, mem);
+   if (ret == -EBUSY)
+   continue;
+
+   goto error;
}
}
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 4/9] drm/amdgpu: allow direct submission of PDE updates v2

2019-09-10 Thread Christian König
For handling PDE updates directly in the fault handler.

v2: fix typo in comment

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c  | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c   | 8 +---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h   | 4 ++--
 5 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d90b647985d7..51ff89cb2f16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -343,7 +343,7 @@ static int vm_update_pds(struct amdgpu_vm *vm, struct 
amdgpu_sync *sync)
struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev);
int ret;
 
-   ret = amdgpu_vm_update_directories(adev, vm);
+   ret = amdgpu_vm_update_pdes(adev, vm, false);
if (ret)
return ret;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 51f3db08b8eb..bd6b88827447 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -845,7 +845,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
if (r)
return r;
 
-   r = amdgpu_vm_update_directories(adev, vm);
+   r = amdgpu_vm_update_pdes(adev, vm, false);
if (r)
return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 22eab74d9998..d4725f98643e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -521,7 +521,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device 
*adev,
goto error;
}
 
-   r = amdgpu_vm_update_directories(adev, vm);
+   r = amdgpu_vm_update_pdes(adev, vm, false);
 
 error:
if (r && r != -ERESTARTSYS)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 8a9ba66c8383..fff553a591b6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1227,18 +1227,19 @@ static void amdgpu_vm_invalidate_pds(struct 
amdgpu_device *adev,
 }
 
 /*
- * amdgpu_vm_update_directories - make sure that all directories are valid
+ * amdgpu_vm_update_pdes - make sure that all directories are valid
  *
  * @adev: amdgpu_device pointer
  * @vm: requested vm
+ * @direct: submit directly to the paging queue
  *
  * Makes sure all directories are up to date.
  *
  * Returns:
  * 0 for success, error for failure.
  */
-int amdgpu_vm_update_directories(struct amdgpu_device *adev,
-struct amdgpu_vm *vm)
+int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
+ struct amdgpu_vm *vm, bool direct)
 {
struct amdgpu_vm_update_params params;
int r;
@@ -1249,6 +1250,7 @@ int amdgpu_vm_update_directories(struct amdgpu_device 
*adev,
memset(¶ms, 0, sizeof(params));
params.adev = adev;
params.vm = vm;
+   params.direct = direct;
 
r = vm->update_funcs->prepare(¶ms, AMDGPU_FENCE_OWNER_VM, NULL);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 54dcd0bcce1a..0a97dc839f3b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -366,8 +366,8 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
  int (*callback)(void *p, struct amdgpu_bo *bo),
  void *param);
 int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool 
need_pipe_sync);
-int amdgpu_vm_update_directories(struct amdgpu_device *adev,
-struct amdgpu_vm *vm);
+int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
+ struct amdgpu_vm *vm, bool direct);
 int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
  struct amdgpu_vm *vm,
  struct dma_fence **fence);
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 5/9] drm/amdgpu: allow direct submission of PTE updates

2019-09-10 Thread Christian König
For handling PTE updates directly in the fault handler.

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index fff553a591b6..aed68fa88f16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1492,13 +1492,14 @@ static int amdgpu_vm_update_ptes(struct 
amdgpu_vm_update_params *params,
  * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
  *
  * @adev: amdgpu_device pointer
- * @exclusive: fence we need to sync to
- * @pages_addr: DMA addresses to use for mapping
  * @vm: requested vm
+ * @direct: direct submission in a page fault
+ * @exclusive: fence we need to sync to
  * @start: start of mapped range
  * @last: last mapped entry
  * @flags: flags for the entries
  * @addr: addr to set the area to
+ * @pages_addr: DMA addresses to use for mapping
  * @fence: optional resulting fence
  *
  * Fill in the page table entries between @start and @last.
@@ -1507,11 +1508,11 @@ static int amdgpu_vm_update_ptes(struct 
amdgpu_vm_update_params *params,
  * 0 for success, -EINVAL for failure.
  */
 static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
+  struct amdgpu_vm *vm, bool direct,
   struct dma_fence *exclusive,
-  dma_addr_t *pages_addr,
-  struct amdgpu_vm *vm,
   uint64_t start, uint64_t last,
   uint64_t flags, uint64_t addr,
+  dma_addr_t *pages_addr,
   struct dma_fence **fence)
 {
struct amdgpu_vm_update_params params;
@@ -1521,6 +1522,7 @@ static int amdgpu_vm_bo_update_mapping(struct 
amdgpu_device *adev,
memset(¶ms, 0, sizeof(params));
params.adev = adev;
params.vm = vm;
+   params.direct = direct;
params.pages_addr = pages_addr;
 
/* sync to everything except eviction fences on unmapping */
@@ -1633,9 +1635,9 @@ static int amdgpu_vm_bo_split_mapping(struct 
amdgpu_device *adev,
}
 
last = min((uint64_t)mapping->last, start + max_entries - 1);
-   r = amdgpu_vm_bo_update_mapping(adev, exclusive, dma_addr, vm,
+   r = amdgpu_vm_bo_update_mapping(adev, vm, false, exclusive,
start, last, flags, addr,
-   fence);
+   dma_addr, fence);
if (r)
return r;
 
@@ -1929,9 +1931,9 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
mapping->start < AMDGPU_GMC_HOLE_START)
init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
 
-   r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm,
+   r = amdgpu_vm_bo_update_mapping(adev, vm, false, NULL,
mapping->start, mapping->last,
-   init_pte_value, 0, &f);
+   init_pte_value, 0, NULL, &f);
amdgpu_vm_free_mapping(adev, vm, mapping, f);
if (r) {
dma_fence_put(f);
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 2/9] drm/amdgpu: split the VM entity into direct and delayed

2019-09-10 Thread Christian König
For page fault handling we need to use a direct update which can't be
blocked by ongoing user CS.

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c |  6 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 21 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c |  5 +++--
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index cd15540c5622..dfe155566571 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -282,7 +282,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
!dma_fence_is_later(updates, (*id)->flushed_updates))
updates = NULL;
 
-   if ((*id)->owner != vm->entity.fence_context ||
+   if ((*id)->owner != vm->direct.fence_context ||
job->vm_pd_addr != (*id)->pd_gpu_addr ||
updates || !(*id)->last_flush ||
((*id)->last_flush->context != fence_context &&
@@ -349,7 +349,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
struct dma_fence *flushed;
 
/* Check all the prerequisites to using this VMID */
-   if ((*id)->owner != vm->entity.fence_context)
+   if ((*id)->owner != vm->direct.fence_context)
continue;
 
if ((*id)->pd_gpu_addr != job->vm_pd_addr)
@@ -449,7 +449,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct 
amdgpu_ring *ring,
}
 
id->pd_gpu_addr = job->vm_pd_addr;
-   id->owner = vm->entity.fence_context;
+   id->owner = vm->direct.fence_context;
 
if (job->vm_needs_flush) {
dma_fence_put(id->last_flush);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index e11764164cbf..8a9ba66c8383 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2670,12 +2670,17 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
spin_lock_init(&vm->invalidated_lock);
INIT_LIST_HEAD(&vm->freed);
 
-   /* create scheduler entity for page table updates */
-   r = drm_sched_entity_init(&vm->entity, adev->vm_manager.vm_pte_rqs,
+   /* create scheduler entities for page table updates */
+   r = drm_sched_entity_init(&vm->direct, adev->vm_manager.vm_pte_rqs,
  adev->vm_manager.vm_pte_num_rqs, NULL);
if (r)
return r;
 
+   r = drm_sched_entity_init(&vm->delayed, adev->vm_manager.vm_pte_rqs,
+ adev->vm_manager.vm_pte_num_rqs, NULL);
+   if (r)
+   goto error_free_direct;
+
vm->pte_support_ats = false;
 
if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE) {
@@ -2704,7 +2709,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
bp.flags &= ~AMDGPU_GEM_CREATE_SHADOW;
r = amdgpu_bo_create(adev, &bp, &root);
if (r)
-   goto error_free_sched_entity;
+   goto error_free_delayed;
 
r = amdgpu_bo_reserve(root, true);
if (r)
@@ -2747,8 +2752,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
amdgpu_bo_unref(&vm->root.base.bo);
vm->root.base.bo = NULL;
 
-error_free_sched_entity:
-   drm_sched_entity_destroy(&vm->entity);
+error_free_delayed:
+   drm_sched_entity_destroy(&vm->delayed);
+
+error_free_direct:
+   drm_sched_entity_destroy(&vm->direct);
 
return r;
 }
@@ -2937,7 +2945,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct 
amdgpu_vm *vm)
spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
}
 
-   drm_sched_entity_destroy(&vm->entity);
+   drm_sched_entity_destroy(&vm->direct);
+   drm_sched_entity_destroy(&vm->delayed);
 
if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
dev_err(adev->dev, "still active bo inside vm\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 3352a87b822e..7138722ee55f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -257,8 +257,9 @@ struct amdgpu_vm {
struct amdgpu_vm_pt root;
struct dma_fence*last_update;
 
-   /* Scheduler entity for page table updates */
-   struct drm_sched_entity entity;
+   /* Scheduler entities for page table updates */
+   struct drm_sched_entity direct;
+   struct drm_sched_entity delayed;
 
unsigned intpasid;
/* dedicated to vm */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index ddd181f5ed37..d087d6650d79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_

[PATCH 9/9] drm/amdgpu: add graceful VM fault handling v3

2019-09-10 Thread Christian König
Next step towards HMM support. For now just silence the retry fault and
optionally redirect the request to the dummy page.

v2: make sure the VM is not destroyed while we handle the fault.
v3: fix VM destroy check, cleanup comments

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 73 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  2 +
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  |  4 ++
 3 files changed, 79 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index db13ddd70a8d..48349e4f0701 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3125,3 +3125,76 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
}
}
 }
+
+/**
+ * amdgpu_vm_handle_fault - graceful handling of VM faults.
+ * @adev: amdgpu device pointer
+ * @pasid: PASID of the VM
+ * @addr: Address of the fault
+ *
+ * Try to gracefully handle a VM fault. Return true if the fault was handled 
and
+ * shouldn't be reported any more.
+ */
+bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
+   uint64_t addr)
+{
+   struct amdgpu_bo *root;
+   uint64_t value, flags;
+   struct amdgpu_vm *vm;
+   long r;
+
+   spin_lock(&adev->vm_manager.pasid_lock);
+   vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
+   if (vm)
+   root = amdgpu_bo_ref(vm->root.base.bo);
+   else
+   root = NULL;
+   spin_unlock(&adev->vm_manager.pasid_lock);
+
+   if (!root)
+   return false;
+
+   r = amdgpu_bo_reserve(root, true);
+   if (r)
+   goto error_unref;
+
+   /* Double check that the VM still exists */
+   spin_lock(&adev->vm_manager.pasid_lock);
+   vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
+   if (vm && vm->root.base.bo != root)
+   vm = NULL;
+   spin_unlock(&adev->vm_manager.pasid_lock);
+   if (!vm)
+   goto error_unlock;
+
+   addr /= AMDGPU_GPU_PAGE_SIZE;
+   flags = AMDGPU_PTE_VALID | AMDGPU_PTE_SNOOPED |
+   AMDGPU_PTE_SYSTEM;
+
+   if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_NEVER) {
+   /* Redirect the access to the dummy page */
+   value = adev->dummy_page_addr;
+   flags |= AMDGPU_PTE_EXECUTABLE | AMDGPU_PTE_READABLE |
+   AMDGPU_PTE_WRITEABLE;
+   } else {
+   /* Let the hw retry silently on the PTE */
+   value = 0;
+   }
+
+   r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr + 1,
+   flags, value, NULL, NULL);
+   if (r)
+   goto error_unlock;
+
+   r = amdgpu_vm_update_pdes(adev, vm, true);
+
+error_unlock:
+   amdgpu_bo_unreserve(root);
+   if (r < 0)
+   DRM_ERROR("Can't handle page fault (%ld)\n", r);
+
+error_unref:
+   amdgpu_bo_unref(&root);
+
+   return false;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 0a97dc839f3b..4dbbe1b6b413 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -413,6 +413,8 @@ void amdgpu_vm_check_compute_bug(struct amdgpu_device 
*adev);
 
 void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid,
 struct amdgpu_task_info *task_info);
+bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
+   uint64_t addr);
 
 void amdgpu_vm_set_task_info(struct amdgpu_vm *vm);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 0d06c7901d26..ad19c8194a73 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -375,6 +375,10 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device 
*adev,
}
 
/* If it's the first fault for this address, process it normally */
+   if (retry_fault && !in_interrupt() &&
+   amdgpu_vm_handle_fault(adev, entry->pasid, addr))
+   return 1; /* This also prevents sending it to KFD */
+
if (!amdgpu_sriov_vf(adev)) {
/*
 * Issue a dummy read to wait for the status register to
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 6/9] drm/amdgpu: allow direct submission of clears

2019-09-10 Thread Christian König
For handling PD/PT clears directly in the fault handler.

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index aed68fa88f16..6c94c5a562cf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -695,6 +695,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
  * @adev: amdgpu_device pointer
  * @vm: VM to clear BO from
  * @bo: BO to clear
+ * @direct: use a direct update
  *
  * Root PD needs to be reserved when calling this.
  *
@@ -703,7 +704,8 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
  */
 static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
  struct amdgpu_vm *vm,
- struct amdgpu_bo *bo)
+ struct amdgpu_bo *bo,
+ bool direct)
 {
struct ttm_operation_ctx ctx = { true, false };
unsigned level = adev->vm_manager.root_level;
@@ -762,6 +764,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
memset(¶ms, 0, sizeof(params));
params.adev = adev;
params.vm = vm;
+   params.direct = direct;
 
r = vm->update_funcs->prepare(¶ms, AMDGPU_FENCE_OWNER_KFD, NULL);
if (r)
@@ -852,7 +855,8 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
  */
 static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
   struct amdgpu_vm *vm,
-  struct amdgpu_vm_pt_cursor *cursor)
+  struct amdgpu_vm_pt_cursor *cursor,
+  bool direct)
 {
struct amdgpu_vm_pt *entry = cursor->entry;
struct amdgpu_bo_param bp;
@@ -885,7 +889,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
pt->parent = amdgpu_bo_ref(cursor->parent->base.bo);
amdgpu_vm_bo_base_init(&entry->base, vm, pt);
 
-   r = amdgpu_vm_clear_bo(adev, vm, pt);
+   r = amdgpu_vm_clear_bo(adev, vm, pt, direct);
if (r)
goto error_free_pt;
 
@@ -1401,7 +1405,8 @@ static int amdgpu_vm_update_ptes(struct 
amdgpu_vm_update_params *params,
uint64_t incr, entry_end, pe_start;
struct amdgpu_bo *pt;
 
-   r = amdgpu_vm_alloc_pts(params->adev, params->vm, &cursor);
+   r = amdgpu_vm_alloc_pts(params->adev, params->vm, &cursor,
+   params->direct);
if (r)
return r;
 
@@ -2725,7 +2730,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
 
amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
 
-   r = amdgpu_vm_clear_bo(adev, vm, root);
+   r = amdgpu_vm_clear_bo(adev, vm, root, false);
if (r)
goto error_unreserve;
 
@@ -2848,7 +2853,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, 
struct amdgpu_vm *vm, uns
 */
if (pte_support_ats != vm->pte_support_ats) {
vm->pte_support_ats = pte_support_ats;
-   r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo);
+   r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo, false);
if (r)
goto free_idr;
}
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 8/9] drm/amdgpu: reserve the root PD while freeing PASIDs

2019-09-10 Thread Christian König
Free the pasid only while the root PD is reserved. This prevents use after
free in the page fault handling.

Signed-off-by: Christian König 
Reviewed-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 3b954b53a450..db13ddd70a8d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2944,18 +2944,26 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct 
amdgpu_vm *vm)
struct amdgpu_bo_va_mapping *mapping, *tmp;
bool prt_fini_needed = !!adev->gmc.gmc_funcs->set_prt;
struct amdgpu_bo *root;
-   int i, r;
+   int i;
 
amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm);
 
+   root = amdgpu_bo_ref(vm->root.base.bo);
+   amdgpu_bo_reserve(root, true);
if (vm->pasid) {
unsigned long flags;
 
spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
idr_remove(&adev->vm_manager.pasid_idr, vm->pasid);
spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
+   vm->pasid = 0;
}
 
+   amdgpu_vm_free_pts(adev, vm, NULL);
+   amdgpu_bo_unreserve(root);
+   amdgpu_bo_unref(&root);
+   WARN_ON(vm->root.base.bo);
+
drm_sched_entity_destroy(&vm->direct);
drm_sched_entity_destroy(&vm->delayed);
 
@@ -2980,16 +2988,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct 
amdgpu_vm *vm)
amdgpu_vm_free_mapping(adev, vm, mapping, NULL);
}
 
-   root = amdgpu_bo_ref(vm->root.base.bo);
-   r = amdgpu_bo_reserve(root, true);
-   if (r) {
-   dev_err(adev->dev, "Leaking page tables because BO reservation 
failed\n");
-   } else {
-   amdgpu_vm_free_pts(adev, vm, NULL);
-   amdgpu_bo_unreserve(root);
-   }
-   amdgpu_bo_unref(&root);
-   WARN_ON(vm->root.base.bo);
dma_fence_put(vm->last_update);
for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
amdgpu_vmid_free_reserved(adev, vm, i);
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

RE: [Patch] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10

2019-09-10 Thread Zhou1, Tao
Reviewed-by: Tao Zhou mailto:tao.zh...@amd.com>>

From: Yin, Tianci (Rico) 
Sent: 2019年9月10日 16:59
To: amd-gfx@lists.freedesktop.org
Cc: Zhang, Hawking ; Zhou1, Tao ; Xu, 
Feifei ; Long, Gang 
Subject: [Patch] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdkfd: fix the missed asic name while inited renoir_device_info

2019-09-10 Thread Huang, Ray
This patch fixes null pointer issue below, I missed to init the asic renior name
while I rebase the patches.

[  106.004250] BUG: kernel NULL pointer dereference, address: 
[  106.004254] #PF: supervisor read access in kernel mode
[  106.004256] #PF: error_code(0x) - not-present page
[  106.004257] PGD 0 P4D 0
[  106.004261] Oops:  [#1] SMP NOPTI
[  106.004264] CPU: 3 PID: 1422 Comm: modprobe Not tainted 5.2.0-rc1-custom #1
[  106.004266] Hardware name: AMD Celadon-RN/Celadon-RN, BIOS
WCD9814N_Weekly_19_08_1 08/14/2019
[  106.004272] RIP: 0010:strncpy+0x12/0x30
[  106.004274] Code: c1 c0 11 48 c1 c6 15 48 31 d0 48 c1 c2 20 31 c2 89 d0 31 f0
41 5c 5d c3 55 48 85 d2 48 89 f8 48 89 e5 74 1e 48 01 fa 48 89 f9 <44> 0f b6 06
41 80 f8 01 44 88 01 48 83 de ff 48 83 c1 01 48 39 d1
[  106.004278] RSP: 0018:c092c1fd37a8 EFLAGS: 00010286
[  106.004281] RAX: 9e943466a28c RBX: 36ed RCX: 9e943466a28c
[  106.004283] RDX: 9e943466a2ac RSI:  RDI: 9e943466a28c
[  106.004285] RBP: c092c1fd37a8 R08: 9e943d10 R09: 0228
[  106.004287] R10: 9e94418dc5a8 R11: 9e944746c0d0 R12: 
[  106.004289] R13: 9e943fa1ec00 R14: 9e943466a200 R15: 9e943466a200
[  106.004291] FS:  7f7a022c5540() GS:9e9447ac()
knlGS:
[  106.004294] CS:  0010 DS:  ES:  CR0: 80050033
[  106.004296] CR2:  CR3: 0001ff0b CR4: 00340ee0
[  106.004298] Call Trace:
[  106.004382]  kfd_topology_add_device+0x150/0x610 [amdgpu]
[  106.004445]  kgd2kfd_device_init+0x2e0/0x4f0 [amdgpu]
[  106.004509]  amdgpu_amdkfd_device_init+0x14c/0x1b0 [amdgpu]

Signed-off-by: Huang Rui 
---
 drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index a2fe0cb..f329b82 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -353,6 +353,7 @@ static const struct kfd_device_info arcturus_device_info = {
 
 static const struct kfd_device_info renoir_device_info = {
.asic_family = CHIP_RENOIR,
+   .asic_name = "renoir",
.max_pasid_bits = 16,
.max_no_of_hqd  = 24,
.doorbell_size  = 8,
-- 
2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

RE: [PATCH] drm/amdkfd: fix the missed asic name while inited renoir_device_info

2019-09-10 Thread Liu, Aaron
Reviewed & Tested-by: Aaron Liu 

BR,
Aaron Liu

> -Original Message-
> From: Huang, Ray 
> Sent: Tuesday, September 10, 2019 7:17 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Kuehling, Felix ; Liu, Aaron
> ; Huang, Ray 
> Subject: [PATCH] drm/amdkfd: fix the missed asic name while inited
> renoir_device_info
> 
> This patch fixes null pointer issue below, I missed to init the asic renior 
> name
> while I rebase the patches.
> 
> [  106.004250] BUG: kernel NULL pointer dereference, address:
>  [  106.004254] #PF: supervisor read access in kernel
> mode [  106.004256] #PF: error_code(0x) - not-present page
> [  106.004257] PGD 0 P4D 0 [  106.004261] Oops:  [#1] SMP NOPTI
> [  106.004264] CPU: 3 PID: 1422 Comm: modprobe Not tainted 5.2.0-rc1-
> custom #1 [  106.004266] Hardware name: AMD Celadon-RN/Celadon-RN,
> BIOS
> WCD9814N_Weekly_19_08_1 08/14/2019
> [  106.004272] RIP: 0010:strncpy+0x12/0x30 [  106.004274] Code: c1 c0 11
> 48 c1 c6 15 48 31 d0 48 c1 c2 20 31 c2 89 d0 31 f0
> 41 5c 5d c3 55 48 85 d2 48 89 f8 48 89 e5 74 1e 48 01 fa 48 89 f9 <44> 0f b6
> 06
> 41 80 f8 01 44 88 01 48 83 de ff 48 83 c1 01 48 39 d1 [  106.004278] RSP:
> 0018:c092c1fd37a8 EFLAGS: 00010286 [  106.004281] RAX:
> 9e943466a28c RBX: 36ed RCX: 9e943466a28c
> [  106.004283] RDX: 9e943466a2ac RSI:  RDI:
> 9e943466a28c [  106.004285] RBP: c092c1fd37a8 R08:
> 9e943d10 R09: 0228 [  106.004287] R10:
> 9e94418dc5a8 R11: 9e944746c0d0 R12: 
> [  106.004289] R13: 9e943fa1ec00 R14: 9e943466a200 R15:
> 9e943466a200 [  106.004291] FS:  7f7a022c5540()
> GS:9e9447ac()
> knlGS:
> [  106.004294] CS:  0010 DS:  ES:  CR0: 80050033
> [  106.004296] CR2:  CR3: 0001ff0b CR4:
> 00340ee0 [  106.004298] Call Trace:
> [  106.004382]  kfd_topology_add_device+0x150/0x610 [amdgpu]
> [  106.004445]  kgd2kfd_device_init+0x2e0/0x4f0 [amdgpu] [  106.004509]
> amdgpu_amdkfd_device_init+0x14c/0x1b0 [amdgpu]
> 
> Signed-off-by: Huang Rui 
> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> index a2fe0cb..f329b82 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> @@ -353,6 +353,7 @@ static const struct kfd_device_info
> arcturus_device_info = {
> 
>  static const struct kfd_device_info renoir_device_info = {
>   .asic_family = CHIP_RENOIR,
> + .asic_name = "renoir",
>   .max_pasid_bits = 16,
>   .max_no_of_hqd  = 24,
>   .doorbell_size  = 8,
> --
> 2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH RFC v4 00/16] new cgroup controller for gpu/drm subsystem

2019-09-10 Thread Michal Hocko
On Fri 06-09-19 08:45:39, Tejun Heo wrote:
> Hello, Daniel.
> 
> On Fri, Sep 06, 2019 at 05:34:16PM +0200, Daniel Vetter wrote:
> > > Hmm... what'd be the fundamental difference from slab or socket memory
> > > which are handled through memcg?  Is system memory used by GPUs have
> > > further global restrictions in addition to the amount of physical
> > > memory used?
> > 
> > Sometimes, but that would be specific resources (kinda like vram),
> > e.g. CMA regions used by a gpu. But probably not something you'll run
> > in a datacenter and want cgroups for ...
> > 
> > I guess we could try to integrate with the memcg group controller. One
> > trouble is that aside from i915 most gpu drivers do not really have a
> > full shrinker, so not sure how that would all integrate.
> 
> So, while it'd great to have shrinkers in the longer term, it's not a
> strict requirement to be accounted in memcg.  It already accounts a
> lot of memory which isn't reclaimable (a lot of slabs and socket
> buffer).

Yeah, having a shrinker is preferred but the memory should better be
reclaimable in some form. If not by any other means then at least bound
to a user process context so that it goes away with a task being killed
by the OOM killer. If that is not the case then we cannot really charge
it because then the memcg controller is of no use. We can tolerate it to
some degree if the amount of memory charged like that is negligible to
the overall size. But from the discussion it seems that these buffers
are really large.
-- 
Michal Hocko
SUSE Labs
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: grab the id mgr lock while accessing passid_mapping

2019-09-10 Thread Chunming Zhou
Reviewed-by: Chunming Zhou 

在 2019/9/10 16:56, Christian König 写道:
> Ping!
>
> Am 09.09.19 um 13:59 schrieb Christian König:
>> Need to make sure that we actually dropping the right fence.
>> Could be done with RCU as well, but to complicated for a fix.
>>
>> Signed-off-by: Christian König 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 12 +---
>>   1 file changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> index b285ab25146d..e11764164cbf 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> @@ -1036,10 +1036,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, 
>> struct amdgpu_job *job, bool need_
>>   id->oa_base != job->oa_base ||
>>   id->oa_size != job->oa_size);
>>   bool vm_flush_needed = job->vm_needs_flush;
>> -    bool pasid_mapping_needed = id->pasid != job->pasid ||
>> -    !id->pasid_mapping ||
>> -    !dma_fence_is_signaled(id->pasid_mapping);
>>   struct dma_fence *fence = NULL;
>> +    bool pasid_mapping_needed;
>>   unsigned patch_offset = 0;
>>   int r;
>>   @@ -1049,6 +1047,12 @@ int amdgpu_vm_flush(struct amdgpu_ring 
>> *ring, struct amdgpu_job *job, bool need_
>>   pasid_mapping_needed = true;
>>   }
>>   +    mutex_lock(&id_mgr->lock);
>> +    if (id->pasid != job->pasid || !id->pasid_mapping ||
>> +    !dma_fence_is_signaled(id->pasid_mapping))
>> +    pasid_mapping_needed = true;
>> +    mutex_unlock(&id_mgr->lock);
>> +
>>   gds_switch_needed &= !!ring->funcs->emit_gds_switch;
>>   vm_flush_needed &= !!ring->funcs->emit_vm_flush &&
>>   job->vm_pd_addr != AMDGPU_BO_INVALID_OFFSET;
>> @@ -1088,9 +1092,11 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, 
>> struct amdgpu_job *job, bool need_
>>   }
>>     if (pasid_mapping_needed) {
>> +    mutex_lock(&id_mgr->lock);
>>   id->pasid = job->pasid;
>>   dma_fence_put(id->pasid_mapping);
>>   id->pasid_mapping = dma_fence_get(fence);
>> +    mutex_unlock(&id_mgr->lock);
>>   }
>>   dma_fence_put(fence);
>
> ___
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

RE: [PATCH 9/9] drm/amdgpu: add graceful VM fault handling v2

2019-09-10 Thread Zeng, Oak


Regards,
Oak

-Original Message-
From: Koenig, Christian  
Sent: Monday, September 9, 2019 1:14 PM
To: Zeng, Oak ; Kuehling, Felix ; 
amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH 9/9] drm/amdgpu: add graceful VM fault handling v2

> Well first of all we are not in interrupt context here, this is handled by a 
> work item or otherwise we couldn't do all the locking.

This is called from amdgpu_irq_handler. I think this is interrupt context. This 
is also the reason why we use spin lock instead of other sleepable lock like a 
semaphore.

> But even in interrupt context another CPU can easily destroy the VM when we 
> just handle a stale fault or the process was killed.

Agree with this point.

So this extra double checking is strictly necessary.

Regards,
Christian.

Am 09.09.19 um 16:08 schrieb Zeng, Oak:
> Is looking up vm twice necessary? I think we are in interrupt context, is it 
> possible that the user space application can be switched in between? My 
> understanding is, if user space application is can't kick in during interrupt 
> handling, application shouldn't have chance to exit (then their vm being 
> destroyed).
>
> Regards,
> Oak
>
> -Original Message-
> From: amd-gfx  On Behalf Of 
> Christian König
> Sent: Monday, September 9, 2019 8:08 AM
> To: Kuehling, Felix ; 
> amd-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 9/9] drm/amdgpu: add graceful VM fault handling v2
>
> Am 05.09.19 um 00:47 schrieb Kuehling, Felix:
>> On 2019-09-04 11:02 a.m., Christian König wrote:
>>> Next step towards HMM support. For now just silence the retry fault 
>>> and optionally redirect the request to the dummy page.
>>>
>>> v2: make sure the VM is not destroyed while we handle the fault.
>>>
>>> Signed-off-by: Christian König 
>>> ---
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 74 ++
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  2 +
>>> drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  |  4 ++
>>> 3 files changed, 80 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> index 951608fc1925..410d89966a66 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> @@ -3142,3 +3142,77 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
>>> }
>>> }
>>> }
>>> +
>>> +/**
>>> + * amdgpu_vm_handle_fault - graceful handling of VM faults.
>>> + * @adev: amdgpu device pointer
>>> + * @pasid: PASID of the VM
>>> + * @addr: Address of the fault
>>> + *
>>> + * Try to gracefully handle a VM fault. Return true if the fault 
>>> +was handled and
>>> + * shouldn't be reported any more.
>>> + */
>>> +bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
>>> +   uint64_t addr)
>>> +{
>>> +   struct amdgpu_ring *ring = &adev->sdma.instance[0].page;
>>> +   struct amdgpu_bo *root;
>>> +   uint64_t value, flags;
>>> +   struct amdgpu_vm *vm;
>>> +   long r;
>>> +
>>> +   if (!ring->sched.ready)
>>> +   return false;
>>> +
>>> +   spin_lock(&adev->vm_manager.pasid_lock);
>>> +   vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
>>> +   if (vm)
>>> +   root = amdgpu_bo_ref(vm->root.base.bo);
>>> +   else
>>> +   root = NULL;
>>> +   spin_unlock(&adev->vm_manager.pasid_lock);
>>> +
>>> +   if (!root)
>>> +   return false;
>>> +
>>> +   r = amdgpu_bo_reserve(root, true);
>>> +   if (r)
>>> +   goto error_unref;
>>> +
>>> +   spin_lock(&adev->vm_manager.pasid_lock);
>>> +   vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
>>> +   spin_unlock(&adev->vm_manager.pasid_lock);
>> I think this deserves a comment. If I understand it correctly, you're 
>> looking up the vm twice so that you have the VM root reservation to 
>> protect against user-after-free. Otherwise the vm pointer is only 
>> valid as long as you're holding the spin-lock.
>>
>>
>>> +
>>> +   if (!vm || vm->root.base.bo != root)
>> The check of vm->root.base.bo should probably still be under the 
>> spin_lock. Because you're not sure yet it's the right VM, you can't 
>> rely on the reservation here to prevent use-after-free.
> Good point, going to fix that.
>
>>
>>> +   goto error_unlock;
>>> +
>>> +   addr /= AMDGPU_GPU_PAGE_SIZE;
>>> +   flags = AMDGPU_PTE_VALID | AMDGPU_PTE_SNOOPED |
>>> +   AMDGPU_PTE_SYSTEM;
>>> +
>>> +   if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_NEVER) {
>>> +   /* Redirect the access to the dummy page */
>>> +   value = adev->dummy_page_addr;
>>> +   flags |= AMDGPU_PTE_EXECUTABLE | AMDGPU_PTE_READABLE |
>>> +   AMDGPU_PTE_WRITEABLE;
>>> +   } else {
>>> +   value = 0;
>>> +   }
>>> +
>>> +   r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr + 1,
>>> +   flags, value, NULL, NULL);
>>> +   if (r)
>>> +   goto error_unlock;
>>> +
>>> +   r = amd

[PATCH 03/25] drm/amd/display: 3.2.50

2019-09-10 Thread sunpeng.li
From: Aric Cyr 

Signed-off-by: Aric Cyr 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 3b848d4aca8c..d21e8fc0179e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.49"
+#define DC_VER "3.2.50"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 02/25] drm/amd/display: define parameters for abm 2.3

2019-09-10 Thread sunpeng.li
From: Josip Pavic 

[Why]
Current configuration 0 is just a placeholder, and final parameters needed.
Also, configuration 1 is expected to emulate ABM 2.1 but is too aggressive.

[How]
Redefine configuration 0 with the finalized parameters, and increase the
contrast gain of configuration 1 so that it properly emulates ABM 2.1.

Signed-off-by: Josip Pavic 
Reviewed-by: Anthony Koo 
Acked-by: Leo Li 
---
 .../amd/display/modules/power/power_helpers.c| 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c 
b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
index 05e2be856037..cc6b794821d9 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -80,18 +80,18 @@ struct abm_parameters {
 
 static const struct abm_parameters abm_settings_config0[abm_defines_max_level] 
= {
 //  min_red  max_red  bright_pos  dark_pos  brightness_gain  contrast  
deviation  min_knee  max_knee
-   {0xff,   0xbf,0x20,   0x00, 0xff,0x99, 
0xb3,  0x40, 0xE0},
-   {0xff,   0x85,0x20,   0x00, 0xff,0x90, 
0xa8,  0x40, 0xE0},
-   {0xff,   0x40,0x20,   0x00, 0xff,0x90, 
0x68,  0x40, 0xE0},
-   {0x82,   0x4d,0x20,   0x00, 0x00,0x90, 
0xb3,  0x70, 0x70},
+   {0xff,   0xbf,0x20,   0x00, 0xff,0x99, 
0xb3,  0x40, 0xe0},
+   {0xde,   0x85,0x20,   0x00, 0xff,0x90, 
0xa8,  0x40, 0xdf},
+   {0xb0,   0x50,0x20,   0x00, 0xc0,0x88, 
0x78,  0x70, 0xa0},
+   {0x82,   0x40,0x20,   0x00, 0x00,0xff, 
0xb3,  0x70, 0x70},
 };
 
 static const struct abm_parameters abm_settings_config1[abm_defines_max_level] 
= {
 //  min_red  max_red  bright_pos  dark_pos  brightness_gain  contrast  
deviation  min_knee  max_knee
-   {0xf0,   0xd9,0x20,   0x00, 0x00,0xa8, 
0xb3,  0x70, 0x70},
-   {0xcd,   0xa5,0x20,   0x00, 0x00,0xa8, 
0xb3,  0x70, 0x70},
-   {0x99,   0x65,0x20,   0x00, 0x00,0xa8, 
0xb3,  0x70, 0x70},
-   {0x82,   0x4d,0x20,   0x00, 0x00,0xa8, 
0xb3,  0x70, 0x70},
+   {0xf0,   0xd9,0x20,   0x00, 0x00,0xff, 
0xb3,  0x70, 0x70},
+   {0xcd,   0xa5,0x20,   0x00, 0x00,0xff, 
0xb3,  0x70, 0x70},
+   {0x99,   0x65,0x20,   0x00, 0x00,0xff, 
0xb3,  0x70, 0x70},
+   {0x82,   0x4d,0x20,   0x00, 0x00,0xff, 
0xb3,  0x70, 0x70},
 };
 
 static const struct abm_parameters * const abm_settings[] = {
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 10/25] drm/amd/display: Handle virtual signal type in disable_link()

2019-09-10 Thread sunpeng.li
From: Martin Tsai 

[Why]
The new implementation changed the behavior to allow process setMode
to DAL when DAL returns empty mode query for unplugged display.
This will trigger additional disable_link().
When unplug HDMI from MST dock, driver will update stream->signal to
"Virtual". disable_link() will call disable_output() if the signal type
is not DP and induce other displays on MST dock show black screen.

[How]
Don't need to process disable_output() if the signal type is virtual.

Signed-off-by: Martin Tsai 
Reviewed-by: Charlene Liu 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 1307b533a3f8..de07577085ce 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2166,8 +2166,10 @@ static void disable_link(struct dc_link *link, enum 
signal_type signal)
dp_set_fec_ready(link, false);
}
 #endif
-   } else
-   link->link_enc->funcs->disable_output(link->link_enc, signal);
+   } else {
+   if (signal != SIGNAL_TYPE_VIRTUAL)
+   link->link_enc->funcs->disable_output(link->link_enc, 
signal);
+   }
 
if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
/* MST disable link only when no stream use the link */
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 11/25] drm/amd/display: fix i2c wtire mot incorrect issue

2019-09-10 Thread sunpeng.li
From: Lewis Huang 

[Why]
I2C write command always send mot = true will cause sink state incorrect.

[How]
1. Remove default i2c write mot = true.
2. Deciding mot flag by is_end_of_payload flag.

Signed-off-by: Lewis Huang 
Reviewed-by: Charlene Liu 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index f70137d67c82..588a07b525a0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -523,7 +523,7 @@ bool dal_ddc_service_query_ddc_data(
 
if (write_size != 0) {
payload.write = true;
-   payload.mot = true;
+   payload.mot = false;
payload.length = write_size;
payload.data = write_buf;
 
@@ -592,7 +592,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
current_payload.i2c_over_aux = payload->i2c_over_aux;
current_payload.length = is_end_of_payload ?
payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE;
-   current_payload.mot = payload->mot ? payload->mot : 
!is_end_of_payload;
+   current_payload.mot = !is_end_of_payload;
current_payload.reply = payload->reply;
current_payload.write = payload->write;
 
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 13/25] drm/amd/display: Do not double-buffer DTO adjustments

2019-09-10 Thread sunpeng.li
From: Wesley Chalmers 

[WHY]
When changing DPP global ref clock, DTO adjustments must take effect
immediately, or else underflow may occur.
It appears the original decision to double-buffer DTO adjustments was made to
prevent underflows that occur when raising DPP ref clock (which is not
double-buffered), but that same decision causes similar issues when
lowering DPP global ref clock. The better solution is to order the
adjustments according to whether clocks are being raised or lowered.

Signed-off-by: Wesley Chalmers 
Reviewed-by: Dmytro Laktyushkin 
Acked-by: Anthony Koo 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c | 21 ---
 1 file changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c
index f9b99f8cfc31..313d3793005e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c
@@ -117,27 +117,6 @@ void dccg2_get_dccg_ref_freq(struct dccg *dccg,
 
 void dccg2_init(struct dccg *dccg)
 {
-   struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
-
-   // Fallthrough intentional to program all available dpp_dto's
-   switch (dccg_dcn->base.ctx->dc->res_pool->pipe_count) {
-   case 6:
-   REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[5], 1);
-   case 5:
-   REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[4], 1);
-   case 4:
-   REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[3], 1);
-   case 3:
-   REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[2], 1);
-   case 2:
-   REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[1], 1);
-   case 1:
-   REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[0], 1);
-   break;
-   default:
-   ASSERT(false);
-   break;
-   }
 }
 
 static const struct dccg_funcs dccg2_funcs = {
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 07/25] drm/amd/display: Add debugfs entry to force YUV420 output

2019-09-10 Thread sunpeng.li
From: Stylon Wang 

[Why]
Even if YUV420 is available for video mode, YUV444 is still
automatically selected. This poses a problem for compliance tests.

[How]
Add a per-connector debugfs entry "force_yuv420_output" to force
selection of YUV420 mode.

Signed-off-by: Stylon Wang 
Reviewed-by: Nicholas Kazlauskas 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  5 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 31 +++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c1031121ee8a..f9c13dccfc03 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3383,7 +3383,7 @@ static void fill_stream_properties_from_drm_display_mode(
 {
struct dc_crtc_timing *timing_out = &stream->timing;
const struct drm_display_info *info = &connector->display_info;
-
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
memset(timing_out, 0, sizeof(struct dc_crtc_timing));
 
timing_out->h_border_left = 0;
@@ -3394,6 +3394,9 @@ static void fill_stream_properties_from_drm_display_mode(
if (drm_mode_is_420_only(info, mode_in)
&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+   else if (drm_mode_is_420_also(info, mode_in)
+   && aconnector->force_yuv420_output)
+   timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
else if ((connector->display_info.color_formats & 
DRM_COLOR_FORMAT_YCRCB444)
&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index cbd6608f58e6..17a35b504552 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -284,6 +284,7 @@ struct amdgpu_dm_connector {
uint32_t debugfs_dpcd_address;
uint32_t debugfs_dpcd_size;
 #endif
+   bool force_yuv420_output;
 };
 
 #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, 
base)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 97bbb934cc04..b99be385eea3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -940,6 +940,33 @@ static const struct {
{"aux_dpcd_data", &dp_dpcd_data_debugfs_fops}
 };
 
+/*
+ * Force YUV420 output if available from the given mode
+ */
+static int force_yuv420_output_set(void *data, u64 val)
+{
+   struct amdgpu_dm_connector *connector = data;
+
+   connector->force_yuv420_output = (bool)val;
+
+   return 0;
+}
+
+/*
+ * Check if YUV420 is forced when available from the given mode
+ */
+static int force_yuv420_output_get(void *data, u64 *val)
+{
+   struct amdgpu_dm_connector *connector = data;
+
+   *val = connector->force_yuv420_output;
+
+   return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
+force_yuv420_output_set, "%llu\n");
+
 void connector_debugfs_init(struct amdgpu_dm_connector *connector)
 {
int i;
@@ -953,6 +980,10 @@ void connector_debugfs_init(struct amdgpu_dm_connector 
*connector)
dp_debugfs_entries[i].fops);
}
}
+
+   debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
+  &force_yuv420_output_fops);
+
 }
 
 /*
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 16/25] drm/amd/display: Set number of pipes to 1 if the second pipe was disabled

2019-09-10 Thread sunpeng.li
From: Nikola Cornij 

[why]
Some ODM-related register settings are inconsistently updated by VBIOS, causing
the state in DC to be invalid, which would then end up crashing in certain
use-cases (such as disable/enable device).

[how]
Check the enabled status of the second pipe when determining the number of
OPTC sources. If the second pipe is disabled, set the number of sources to 1
regardless of other settings (that may not be updated correctly).

Signed-off-by: Nikola Cornij 
Reviewed-by: Dmytro Laktyushkin 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
index 2137e2be2140..dda90995ba93 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
@@ -287,6 +287,10 @@ void optc2_get_optc_source(struct timing_generator *optc,
*num_of_src_opp = 2;
else
*num_of_src_opp = 1;
+
+   /* Work around VBIOS not updating OPTC_NUM_OF_INPUT_SEGMENT */
+   if (*src_opp_id_1 == 0xf)
+   *num_of_src_opp = 1;
 }
 
 void optc2_set_dwb_source(struct timing_generator *optc,
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 09/25] drm/amd/display: fix global sync param extraction indexing

2019-09-10 Thread sunpeng.li
From: Dmytro Laktyushkin 

dcn20_calculate_dlg_params was incorrectly indexing pipe src and
dst structs when extracting global sync params.

Signed-off-by: Dmytro Laktyushkin 
Reviewed-by: Jaehyun Chung 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 9aceb159bef5..49a147661cd4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2638,8 +2638,8 @@ void dcn20_calculate_dlg_params(
continue;
 
if (!visited[pipe_idx]) {
-   display_pipe_source_params_st *src = 
&pipes[pipe_idx_unsplit].pipe.src;
-   display_pipe_dest_params_st *dst = 
&pipes[pipe_idx_unsplit].pipe.dest;
+   display_pipe_source_params_st *src = 
&pipes[pipe_idx].pipe.src;
+   display_pipe_dest_params_st *dst = 
&pipes[pipe_idx].pipe.dest;
 
dst->vstartup_start = 
context->bw_ctx.dml.vba.VStartup[pipe_idx_unsplit];
dst->vupdate_offset = 
context->bw_ctx.dml.vba.VUpdateOffsetPix[pipe_idx_unsplit];
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 06/25] drm/amd/display: add additional flag consideration for surface update

2019-09-10 Thread sunpeng.li
From: Dmytro Laktyushkin 

Surface dchub/dpp update would not trigger if a stream update was the
only cause. This change now allows stream flags to trigger this update.

Signed-off-by: Dmytro Laktyushkin 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 81740e0c4c4e..faaf8841c61e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1375,7 +1375,7 @@ static void dcn20_program_pipe(
if (pipe_ctx->update_flags.bits.enable)
dcn20_enable_plane(dc, pipe_ctx, context);
 
-   if (pipe_ctx->update_flags.raw || 
pipe_ctx->plane_state->update_flags.raw)
+   if (pipe_ctx->update_flags.raw || 
pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
 
if (pipe_ctx->update_flags.bits.enable
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 04/25] drm/amd/display: Rebuild mapped resources after pipe split

2019-09-10 Thread sunpeng.li
From: Mikita Lipski 

[why]
The issue is specific for linux, as on timings such as 8K@60
or 4K@144 DSC should be working in combination with ODM Combine
in order to ensure that we can run those timings. The validation
for those timings was passing, but when pipe split was happening
second pipe wasn't being programmed.

[how]
Rebuild mapped resources if we split stream for ODM.

Signed-off-by: Mikita Lipski 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 1 +
 1 file changed, 1 insertion(+)

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 62e9a9826c97..9aceb159bef5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2466,6 +2466,7 @@ bool dcn20_fast_validate_bw(
&context->res_ctx, 
dc->res_pool,
pipe, hsplit_pipe))
goto validate_fail;
+   dcn20_build_mapped_resource(dc, 
context, pipe->stream);
} else
dcn20_split_stream_for_mpc(
&context->res_ctx, dc->res_pool,
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 15/25] drm/amd/display: set minimum abm backlight level

2019-09-10 Thread sunpeng.li
From: Anthony Koo 

[Why]
A lot of the time, the backlight characteristic curve maps min backlight
to a non-zero value.
But there are cases where we want the curve to intersect at 0.
In this scenario even if OS never asks to set 0% backlight, the ABM
reduction can result in backlight being lowered close to 0.
This particularly can cause problems in some LED drivers, and in
general just looks like backlight is completely off.

[How]
Add default cap to disallow backlight from dropping below 1%
even after ABM reduction is applied.

Signed-off-by: Anthony Koo 
Reviewed-by: Aric Cyr 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  5 ++
 .../amd/display/modules/power/power_helpers.c | 77 +++
 .../amd/display/modules/power/power_helpers.h |  1 +
 3 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c7871ddb5df4..7d62b4e86386 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -940,6 +940,11 @@ static int dm_late_init(void *handle)
params.backlight_lut_array_size = 16;
params.backlight_lut_array = linear_lut;
 
+   /* Min backlight level after ABM reduction,  Don't allow below 1%
+* 0x x 0.01 = 0x28F
+*/
+   params.min_abm_backlight = 0x28F;
+
/* todo will enable for navi10 */
if (adev->asic_type <= CHIP_RAVEN) {
ret = dmcu_load_iram(dmcu, params);
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c 
b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
index cc6b794821d9..4e2f615c3566 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -115,7 +115,7 @@ static const struct abm_parameters * const abm_settings[] = 
{
 /* NOTE: iRAM is 256B in size */
 struct iram_table_v_2 {
/* flags  */
-   uint16_t flags; /* 0x00 
U16  */
+   uint16_t min_abm_backlight; /* 0x00 
U16  */
 
/* parameters for ABM2.0 algorithm */
uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];  /* 0x02 
U0.8 */
@@ -140,10 +140,10 @@ struct iram_table_v_2 {
 
/* For reading PSR State directly from IRAM */
uint8_t psr_state;  /* 0xf0 
  */
-   uint8_t dmcu_mcp_interface_version; 
/* 0xf1   */
-   uint8_t dmcu_abm_feature_version;   
/* 0xf2   */
-   uint8_t dmcu_psr_feature_version;   
/* 0xf3   */
-   uint16_t dmcu_version;  
/* 0xf4   */
+   uint8_t dmcu_mcp_interface_version; /* 0xf1 
  */
+   uint8_t dmcu_abm_feature_version;   /* 0xf2 
  */
+   uint8_t dmcu_psr_feature_version;   /* 0xf3 
  */
+   uint16_t dmcu_version;  /* 0xf4 
  */
uint8_t dmcu_state; /* 0xf6 
  */
 
uint16_t blRampReduction;   /* 0xf7 
  */
@@ -164,42 +164,43 @@ struct iram_table_v_2_2 {
uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];  /* 0x16 
U0.8 */
uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];/* 0x2a 
U2.6 */
uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];  /* 0x3e 
U2.6 */
-   uint8_t hybrid_factor[NUM_AGGR_LEVEL];  
/* 0x52 U0.8 */
-   uint8_t contrast_factor[NUM_AGGR_LEVEL];
/* 0x56 U0.8 */
-   uint8_t deviation_gain[NUM_AGGR_LEVEL]; 
/* 0x5a U0.8 */
-   uint8_t iir_curve[NUM_AMBI_LEVEL];  
/* 0x5e U0.8 */
-   uint8_t min_knee[NUM_AGGR_LEVEL];   
/* 0x63 U0.8 */
-   uint8_t max_knee[NUM_AGGR_LEVEL];   
/* 0x67 U0.8 */
-   uint8_t pad[21];
/* 0x6b U0.8 */
+   uint8_t hybrid_factor[NUM_AGGR_LEVEL];  /* 0x52 
U0.8 */
+   uint8_t contrast_factor[NUM_AGGR_LEVEL];/* 0x56 
U0.8 */
+   uint8_t deviation_gain[NUM_AGGR_LEVEL]; /* 0x5a 
U0.8 */
+   uint8_t iir_curve[NUM_AMBI_LEVEL];   

[PATCH 01/25] drm/amd/display: Fix HUBP secondary viewport programming

2019-09-10 Thread sunpeng.li
From: Ilya Bakoulin 

[Why]
Secondary viewport dimension/position registers are not programmed,
which can cause issues in some stereo configurations.

[How]
Add register definitions and register programming.

Signed-off-by: Ilya Bakoulin 
Reviewed-by: Charlene Liu 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c |  8 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h | 12 
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 001db49e4bb2..14d1be6c66e6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -841,6 +841,14 @@ void min_set_viewport(
REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0,
  PRI_VIEWPORT_X_START_C, viewport_c->x,
  PRI_VIEWPORT_Y_START_C, viewport_c->y);
+
+   REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C, 0,
+ SEC_VIEWPORT_WIDTH_C, viewport_c->width,
+ SEC_VIEWPORT_HEIGHT_C, viewport_c->height);
+
+   REG_SET_2(DCSURF_SEC_VIEWPORT_START_C, 0,
+ SEC_VIEWPORT_X_START_C, viewport_c->x,
+ SEC_VIEWPORT_Y_START_C, viewport_c->y);
 }
 
 void hubp1_read_state_common(struct hubp *hubp)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index f8e82ef24c09..ae70d9c0aa1d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -47,6 +47,8 @@
SRI(DCSURF_SEC_VIEWPORT_START, HUBP, id), \
SRI(DCSURF_PRI_VIEWPORT_DIMENSION_C, HUBP, id), \
SRI(DCSURF_PRI_VIEWPORT_START_C, HUBP, id), \
+   SRI(DCSURF_SEC_VIEWPORT_DIMENSION_C, HUBP, id), \
+   SRI(DCSURF_SEC_VIEWPORT_START_C, HUBP, id), \
SRI(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, HUBPREQ, id),\
SRI(DCSURF_PRIMARY_SURFACE_ADDRESS, HUBPREQ, id),\
SRI(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, HUBPREQ, id),\
@@ -154,6 +156,8 @@
uint32_t DCSURF_SEC_VIEWPORT_START; \
uint32_t DCSURF_PRI_VIEWPORT_DIMENSION_C; \
uint32_t DCSURF_PRI_VIEWPORT_START_C; \
+   uint32_t DCSURF_SEC_VIEWPORT_DIMENSION_C; \
+   uint32_t DCSURF_SEC_VIEWPORT_START_C; \
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; \
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; \
uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH; \
@@ -287,6 +291,10 @@
HUBP_SF(HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_C, PRI_VIEWPORT_HEIGHT_C, 
mask_sh),\
HUBP_SF(HUBP0_DCSURF_PRI_VIEWPORT_START_C, PRI_VIEWPORT_X_START_C, 
mask_sh),\
HUBP_SF(HUBP0_DCSURF_PRI_VIEWPORT_START_C, PRI_VIEWPORT_Y_START_C, 
mask_sh),\
+   HUBP_SF(HUBP0_DCSURF_SEC_VIEWPORT_DIMENSION_C, SEC_VIEWPORT_WIDTH_C, 
mask_sh),\
+   HUBP_SF(HUBP0_DCSURF_SEC_VIEWPORT_DIMENSION_C, SEC_VIEWPORT_HEIGHT_C, 
mask_sh),\
+   HUBP_SF(HUBP0_DCSURF_SEC_VIEWPORT_START_C, SEC_VIEWPORT_X_START_C, 
mask_sh),\
+   HUBP_SF(HUBP0_DCSURF_SEC_VIEWPORT_START_C, SEC_VIEWPORT_Y_START_C, 
mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 
PRIMARY_SURFACE_ADDRESS_HIGH, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS, 
PRIMARY_SURFACE_ADDRESS, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 
SECONDARY_SURFACE_ADDRESS_HIGH, mask_sh),\
@@ -481,6 +489,10 @@
type PRI_VIEWPORT_HEIGHT_C; \
type PRI_VIEWPORT_X_START_C; \
type PRI_VIEWPORT_Y_START_C; \
+   type SEC_VIEWPORT_WIDTH_C; \
+   type SEC_VIEWPORT_HEIGHT_C; \
+   type SEC_VIEWPORT_X_START_C; \
+   type SEC_VIEWPORT_Y_START_C; \
type PRIMARY_SURFACE_ADDRESS_HIGH;\
type PRIMARY_SURFACE_ADDRESS;\
type SECONDARY_SURFACE_ADDRESS_HIGH;\
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 22/25] drm/amd/display: 3.4.51.1

2019-09-10 Thread sunpeng.li
From: Aric Cyr 

Signed-off-by: Aric Cyr 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 7c19ac71b424..3ecc42987b05 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.51"
+#define DC_VER "3.2.51.1"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 12/25] drm/amd/display: Separate hardware initialization from creation

2019-09-10 Thread sunpeng.li
From: Julian Parkin 

[Why]
Separating the hardware initialization from the creation of the
dc structures gives greater flexibility to the dm to override
options for debugging.

[How]
Move the hardware initialization call to a new function,
dc_hardware_init. No functional change is intended.

Signed-off-by: Julian Parkin 
Reviewed-by: Tony Cheng 
Acked-by: Leo Li 
Acked-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 8 +---
 drivers/gpu/drm/amd/display/dc/dc.h   | 2 ++
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f9c13dccfc03..c7871ddb5df4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -711,6 +711,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
goto error;
}
 
+   dc_hardware_init(adev->dm.dc);
+
adev->dm.freesync_module = mod_freesync_create(adev->dm.dc);
if (!adev->dm.freesync_module) {
DRM_ERROR(
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 175275560e75..0d7ef89b17a4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -787,9 +787,6 @@ struct dc *dc_create(const struct dc_init_data *init_params)
if (false == construct(dc, init_params))
goto construct_fail;
 
-   /*TODO: separate HW and SW initialization*/
-   dc->hwss.init_hw(dc);
-
full_pipe_count = dc->res_pool->pipe_count;
if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE)
full_pipe_count--;
@@ -822,6 +819,11 @@ struct dc *dc_create(const struct dc_init_data 
*init_params)
return NULL;
 }
 
+void dc_hardware_init(struct dc *dc)
+{
+   dc->hwss.init_hw(dc);
+}
+
 void dc_init_callbacks(struct dc *dc,
const struct dc_callback_init *init_params)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index d21e8fc0179e..30ef31a788f8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -556,6 +556,8 @@ struct dc_callback_init {
 };
 
 struct dc *dc_create(const struct dc_init_data *init_params);
+void dc_hardware_init(struct dc *dc);
+
 int dc_get_vmid_use_vector(struct dc *dc);
 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
 void dc_setup_vm_context(struct dc *dc, struct dc_virtual_addr_space_config 
*va_config, int vmid);
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 14/25] drm/amd/display: Revert fixup DPP programming sequence

2019-09-10 Thread sunpeng.li
From: Wesley Chalmers 

[WHY]
This change was made because DTO programming was double-buffered, which
is itself an issue. After deactivating the DTO double buffer, this
change becomes unnecessary.

This reverts commit 79a0feda4306a2e46872fffd1e5507b8e1785244

Signed-off-by: Wesley Chalmers 
Reviewed-by: Dmytro Laktyushkin 
Acked-by: Anthony Koo 
Acked-by: Leo Li 
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 111 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c  |   3 -
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   3 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c |  31 +
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h |   2 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c|   3 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |   2 +-
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   1 +
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |  10 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |   3 +-
 10 files changed, 48 insertions(+), 121 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index f1df32664414..559e16983f91 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -104,6 +104,7 @@ void dcn20_update_clocks_update_dpp_dto(struct 
clk_mgr_internal *clk_mgr,
 {
int i;
 
+   clk_mgr->dccg->ref_dppclk = clk_mgr->base.clks.dppclk_khz;
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
int dpp_inst, dppclk_khz;
 
@@ -113,75 +114,28 @@ void dcn20_update_clocks_update_dpp_dto(struct 
clk_mgr_internal *clk_mgr,
dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
dppclk_khz = 
context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
clk_mgr->dccg->funcs->update_dpp_dto(
-   clk_mgr->dccg, dpp_inst, dppclk_khz, false);
+   clk_mgr->dccg, dpp_inst, dppclk_khz);
}
 }
 
-static void update_global_dpp_clk(struct clk_mgr_internal *clk_mgr, unsigned 
int khz)
+void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
 {
int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
-   * clk_mgr->dentist_vco_freq_khz / khz;
-
-   uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
-
-   REG_UPDATE(DENTIST_DISPCLK_CNTL,
-   DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider);
-   REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100);
-}
-
-static void update_display_clk(struct clk_mgr_internal *clk_mgr, unsigned int 
khz)
-{
+   * clk_mgr->dentist_vco_freq_khz / 
clk_mgr->base.clks.dppclk_khz;
int disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
-   * clk_mgr->dentist_vco_freq_khz / khz;
+   * clk_mgr->dentist_vco_freq_khz / 
clk_mgr->base.clks.dispclk_khz;
 
+   uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
uint32_t dispclk_wdivider = dentist_get_did_from_divider(disp_divider);
 
REG_UPDATE(DENTIST_DISPCLK_CNTL,
DENTIST_DISPCLK_WDIVIDER, dispclk_wdivider);
+// REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 5, 100);
+   REG_UPDATE(DENTIST_DISPCLK_CNTL,
+   DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider);
+   REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100);
 }
 
-static void request_voltage_and_program_disp_clk(struct clk_mgr *clk_mgr_base, 
unsigned int khz)
-{
-   struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
-   struct dc *dc = clk_mgr_base->ctx->dc;
-   struct pp_smu_funcs_nv *pp_smu = NULL;
-   bool going_up = clk_mgr->base.clks.dispclk_khz < khz;
-
-   if (dc->res_pool->pp_smu)
-   pp_smu = &dc->res_pool->pp_smu->nv_funcs;
-
-   clk_mgr->base.clks.dispclk_khz = khz;
-
-   if (going_up && pp_smu && pp_smu->set_voltage_by_freq)
-   pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_DISPCLK, 
clk_mgr_base->clks.dispclk_khz / 1000);
-
-   update_display_clk(clk_mgr, khz);
-
-   if (!going_up && pp_smu && pp_smu->set_voltage_by_freq)
-   pp_smu->set_voltage_by_freq(&pp_smu->pp_smu, PP_SMU_NV_DISPCLK, 
clk_mgr_base->clks.dispclk_khz / 1000);
-}
-
-static void request_voltage_and_program_global_dpp_clk(struct clk_mgr 
*clk_mgr_base, unsigned int khz)
-{
-   struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
-   struct dc *dc = clk_mgr_base->ctx->dc;
-   struct pp_smu_funcs_nv *pp_smu = NULL;
-   bool going_up = clk_mgr->base.clks.dppclk_khz < khz;
-
-   if (dc->res_pool->pp_smu)
-   pp_smu = &dc->res_pool->pp_smu->nv_funcs;
-
-   clk_mgr->base.clks.dppclk_khz = khz;
-   clk_mgr->dccg->ref_dppclk 

[PATCH 23/25] drm/amd/display: fix use of uninitialized variable

2019-09-10 Thread sunpeng.li
From: Martin Leung 

tg_inst may be used uninitialized, so initialize it to 0.

Signed-off-by: Martin Leung 
Reviewed-by: Jaehyun Chung 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 2 +-
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index cadb255826be..b52c457d209e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -971,7 +971,7 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc,
 {
struct timing_generator *tg;
struct dc_link *link = sink->link;
-   unsigned int enc_inst, tg_inst, i;
+   unsigned int i, enc_inst, tg_inst = 0;
 
// Seamless port only support single DP and EDP so far
if (sink->sink_signal != SIGNAL_TYPE_DISPLAY_PORT &&
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index af85d6cf4427..23313c8808b3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1845,7 +1845,7 @@ static int acquire_resource_from_hw_enabled_state(
struct dc_stream_state *stream)
 {
struct dc_link *link = stream->link;
-   unsigned int inst, tg_inst, i;
+   unsigned int i, inst, tg_inst = 0;
 
/* Check for enabled DIG to identify enabled display */
if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 19/25] drm/amd/display: enable single dp seamless boot

2019-09-10 Thread sunpeng.li
From: Martin Leung 

[why]
seamless boot didn't work for non edp's before

[how]
removed edp-specific code, made dp read uefi-set link settings. Also fixed
a hubbub code line to be consistent with usage of function.

Signed-off-by: Martin Leung 
Reviewed-by: Jun Lei 
Acked-by: Anthony Koo 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 30 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 57 ---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 26 -
 .../drm/amd/display/dc/dcn20/dcn20_hubbub.c   |  5 +-
 4 files changed, 71 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 0d7ef89b17a4..cadb255826be 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -971,29 +971,33 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc,
 {
struct timing_generator *tg;
struct dc_link *link = sink->link;
-   unsigned int enc_inst, tg_inst;
+   unsigned int enc_inst, tg_inst, i;
+
+   // Seamless port only support single DP and EDP so far
+   if (sink->sink_signal != SIGNAL_TYPE_DISPLAY_PORT &&
+   sink->sink_signal != SIGNAL_TYPE_EDP)
+   return false;
 
/* Check for enabled DIG to identify enabled display */
if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
return false;
 
-   /* Check for which front end is used by this encoder.
-* Note the inst is 1 indexed, where 0 is undefined.
-* Note that DIG_FE can source from different OTG but our
-* current implementation always map 1-to-1, so this code makes
-* the same assumption and doesn't check OTG source.
-*/
enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
 
-   /* Instance should be within the range of the pool */
-   if (enc_inst >= dc->res_pool->pipe_count)
+   if (enc_inst == ENGINE_ID_UNKNOWN)
return false;
 
-   if (enc_inst >= dc->res_pool->stream_enc_count)
-   return false;
+   for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
+   if (dc->res_pool->stream_enc[i]->id == enc_inst) {
+   tg_inst = 
dc->res_pool->stream_enc[i]->funcs->dig_source_otg(
+   dc->res_pool->stream_enc[i]);
+   break;
+   }
+   }
 
-   tg_inst = dc->res_pool->stream_enc[enc_inst]->funcs->dig_source_otg(
-   dc->res_pool->stream_enc[enc_inst]);
+   // tg_inst not found
+   if (i == dc->res_pool->stream_enc_count)
+   return false;
 
if (tg_inst >= dc->res_pool->timing_generator_count)
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index de07577085ce..d6d1eca77665 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -517,7 +517,7 @@ static void link_disconnect_remap(struct dc_sink 
*prev_sink, struct dc_link *lin
 }
 
 
-static void read_edp_current_link_settings_on_detect(struct dc_link *link)
+static void read_current_link_settings_on_detect(struct dc_link *link)
 {
union lane_count_set lane_count_set = { {0} };
uint8_t link_bw_set;
@@ -552,17 +552,23 @@ static void 
read_edp_current_link_settings_on_detect(struct dc_link *link)
&link_bw_set, sizeof(link_bw_set));
 
if (link_bw_set == 0) {
-   /* If standard link rates are not being used,
-* Read DPCD 00115h to find the link rate set used
-*/
-   core_link_read_dpcd(link, DP_LINK_RATE_SET,
-   &link_rate_set, sizeof(link_rate_set));
-
-   if (link_rate_set < 
link->dpcd_caps.edp_supported_link_rates_count) {
-   link->cur_link_settings.link_rate =
-   
link->dpcd_caps.edp_supported_link_rates[link_rate_set];
-   link->cur_link_settings.link_rate_set = link_rate_set;
-   link->cur_link_settings.use_link_rate_set = true;
+   if (link->connector_signal == SIGNAL_TYPE_EDP) {
+   /* If standard link rates are not being used,
+* Read DPCD 00115h to find the edp link rate set used
+*/
+   core_link_read_dpcd(link, DP_LINK_RATE_SET,
+   &link_rate_set, sizeof(link_rate_set));
+
+   // edp_supported_link_rates_count = 0 for DP
+   if (link_rate_set < 
link->dpcd_caps.edp_supported_link_rates_count) {
+   link->cur_link_settings.link_rate =
+   
link->dpcd_caps.edp_supported_link_r

[PATCH 18/25] drm/amd/display: update odm mode validation to be in line with policy

2019-09-10 Thread sunpeng.li
From: Dmytro Laktyushkin 

Previously 8k30 worked with dsc and odm combine due to a workaround that ran
the formula a second time with dsc support enable should dsc validation fail.
This worked when clocks were low enough for formula to enable odm to lower
voltage, however now broke due to increased clocks.

This change updates the ODM combine policy within the formula to properly
reflect our current policy within DC, only enabling ODM when we have to, as
well as adding a check for viewport width when dsc is enabled.

As a side effect the redundant call to dml when odm is required is now
unnecessary.

Signed-off-by: Dmytro Laktyushkin 
Reviewed-by: Nikola Cornij 
Acked-by: Leo Li 
---
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 22 +--
 .../dc/dml/dcn20/display_mode_vba_20v2.c  |  9 +++-
 2 files changed, 9 insertions(+), 22 deletions(-)

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 d1901ab5fb8c..8d81c65157d4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2246,11 +2246,7 @@ bool dcn20_fast_validate_bw(
bool out = false;
 
int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
-   bool odm_capable = context->bw_ctx.dml.ip.odm_capable;
bool force_split = false;
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-   bool failed_non_odm_dsc = false;
-#endif
int split_threshold = dc->res_pool->pipe_count / 2;
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
 
@@ -2327,24 +2323,8 @@ bool dcn20_fast_validate_bw(
goto validate_out;
}
 
-   context->bw_ctx.dml.ip.odm_capable = 0;
-
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
 
-   context->bw_ctx.dml.ip.odm_capable = odm_capable;
-
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-   /* 1 dsc per stream dsc validation */
-   if (vlevel <= context->bw_ctx.dml.soc.num_states)
-   if (!dcn20_validate_dsc(dc, context)) {
-   failed_non_odm_dsc = true;
-   vlevel = context->bw_ctx.dml.soc.num_states + 1;
-   }
-#endif
-
-   if (vlevel > context->bw_ctx.dml.soc.num_states && odm_capable)
-   vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, 
pipe_cnt);
-
if (vlevel > context->bw_ctx.dml.soc.num_states)
goto validate_fail;
 
@@ -2480,7 +2460,7 @@ bool dcn20_fast_validate_bw(
}
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
/* Actual dsc count per stream dsc validation*/
-   if (failed_non_odm_dsc && !dcn20_validate_dsc(dc, context)) {
+   if (!dcn20_validate_dsc(dc, context)) {

context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]
 =
DML_FAIL_DSC_VALIDATION_FAILURE;
goto validate_fail;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
index 0fafd693ffb4..841ed6c23f93 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
@@ -38,6 +38,7 @@
 
 #define BPP_INVALID 0
 #define BPP_BLENDED_PIPE 0x
+#define DCN20_MAX_DSC_IMAGE_WIDTH 5184
 
 static double adjust_ReturnBW(
struct display_mode_lib *mode_lib,
@@ -3901,6 +3902,10 @@ void 
dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
mode_lib->vba.MaximumSwathWidthInLineBuffer);
}
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+   double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown(
+   mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states],
+   mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+
for (j = 0; j < 2; j++) {
mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = 
RoundToDFSGranularityDown(
mode_lib->vba.MaxDispclk[i],
@@ -3925,7 +3930,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode
&& i == 
mode_lib->vba.soc.num_states)

mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] 
/ 2
* (1 + 
mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
-   if (mode_lib->vba.ODMCapability == false || 
mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= 
mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+   if (mode_lib->vba.ODMCapability == false ||
+   
(locals->PlaneRequiredDISPCLKWitho

[PATCH 17/25] drm/amd/display: Optimize clocks on clock change

2019-09-10 Thread sunpeng.li
From: Wesley Chalmers 

[WHY]
Presently, there is no way for clocks to be lowered, only raised.

[HOW]
Compare clock status against previous known clock status, and optimize
if different.
This requires re-ordering the layout of the dc_clocks structure, as the
current ordering allows identical clock states to appear different.

Signed-off-by: Wesley Chalmers 
Reviewed-by: Aric Cyr 
Acked-by: Anthony Koo 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++
 drivers/gpu/drm/amd/display/dc/dc.h  | 8 
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8ec80151636d..0d7ef89b17a4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1643,6 +1643,9 @@ enum surface_update_type 
dc_check_update_surfaces_for_stream(
updates[i].surface->update_flags.raw = 0x;
}
 
+   if (type == UPDATE_TYPE_FAST && 
memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, 
offsetof(struct dc_clocks, prev_p_state_change_support)) != 0)
+   dc->optimized_required = true;
+
return type;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 30ef31a788f8..c65f34aa2523 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -252,11 +252,7 @@ enum wm_report_mode {
  */
 struct dc_clocks {
int dispclk_khz;
-   int max_supported_dppclk_khz;
-   int max_supported_dispclk_khz;
int dppclk_khz;
-   int bw_dppclk_khz; /*a copy of dppclk_khz*/
-   int bw_dispclk_khz;
int dcfclk_khz;
int socclk_khz;
int dcfclk_deep_sleep_khz;
@@ -270,6 +266,10 @@ struct dc_clocks {
 * optimization required
 */
bool prev_p_state_change_support;
+   int max_supported_dppclk_khz;
+   int max_supported_dispclk_khz;
+   int bw_dppclk_khz; /*a copy of dppclk_khz*/
+   int bw_dispclk_khz;
 };
 
 struct dc_bw_validation_profile {
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 08/25] drm/amd/display: add vtg update after global sync update

2019-09-10 Thread sunpeng.li
From: Dmytro Laktyushkin 

Global sync update was missing vtg update resulting in underflow if
vstartup decreased a significant amount.

Signed-off-by: Dmytro Laktyushkin 
Reviewed-by: Jaehyun Chung 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

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 faaf8841c61e..4bb5ad19c4cf 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1361,7 +1361,7 @@ static void dcn20_program_pipe(
&& !pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe)
dc->hwss.blank_pixel_data(dc, pipe_ctx, 
!pipe_ctx->plane_state->visible);
 
-   if (pipe_ctx->update_flags.bits.global_sync)
+   if (pipe_ctx->update_flags.bits.global_sync) {
pipe_ctx->stream_res.tg->funcs->program_global_sync(
pipe_ctx->stream_res.tg,
pipe_ctx->pipe_dlg_param.vready_offset,
@@ -1369,6 +1369,10 @@ static void dcn20_program_pipe(
pipe_ctx->pipe_dlg_param.vupdate_offset,
pipe_ctx->pipe_dlg_param.vupdate_width);
 
+   pipe_ctx->stream_res.tg->funcs->set_vtg_params(
+   pipe_ctx->stream_res.tg, 
&pipe_ctx->stream->timing);
+   }
+
if (pipe_ctx->update_flags.bits.odm)
dc->hwss.update_odm(dc, context, pipe_ctx);
 
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 20/25] drm/amd/display: 3.4.51

2019-09-10 Thread sunpeng.li
From: Aric Cyr 

Signed-off-by: Aric Cyr 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index c65f34aa2523..7c19ac71b424 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.50"
+#define DC_VER "3.2.51"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 24/25] drm/amd/display: Add detile buffer size for DCN20

2019-09-10 Thread sunpeng.li
From: Dmytro Laktyushkin 

Detile buffer size affects dcc caps and therefore needs to be
corrected for each ip.

Signed-off-by: Dmytro Laktyushkin 
Reviewed-by: Chris Park 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 7 ---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.h | 1 +
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
index e0a6e30ac3e1..8b8438566101 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -186,14 +186,13 @@ static void hubbub2_get_blk256_size(unsigned int 
*blk256_width, unsigned int *bl
 }
 
 static void hubbub2_det_request_size(
+   unsigned int detile_buf_size,
unsigned int height,
unsigned int width,
unsigned int bpe,
bool *req128_horz_wc,
bool *req128_vert_wc)
 {
-   unsigned int detile_buf_size = 164 * 1024;  /* 164KB for DCN1.0 */
-
unsigned int blk256_height = 0;
unsigned int blk256_width = 0;
unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
@@ -236,7 +235,8 @@ bool hubbub2_get_dcc_compression_cap(struct hubbub *hubbub,
&segment_order_horz, &segment_order_vert))
return false;
 
-   hubbub2_det_request_size(input->surface_size.height,  
input->surface_size.width,
+   hubbub2_det_request_size(TO_DCN20_HUBBUB(hubbub)->detile_buf_size,
+   input->surface_size.height,  input->surface_size.width,
bpe, &req128_horz_wc, &req128_vert_wc);
 
if (!req128_horz_wc && !req128_vert_wc) {
@@ -619,4 +619,5 @@ void hubbub2_construct(struct dcn20_hubbub *hubbub,
hubbub->masks = hubbub_mask;
 
hubbub->debug_test_index_pstate = 0xB;
+   hubbub->detile_buf_size = 164 * 1024; /* 164KB for DCN2.0 */
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.h 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.h
index 626117d3b4e9..501532dd523a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.h
@@ -81,6 +81,7 @@ struct dcn20_hubbub {
unsigned int debug_test_index_pstate;
struct dcn_watermark_set watermarks;
struct dcn20_vmid vmid[16];
+   unsigned int detile_buf_size;
 };
 
 void hubbub2_construct(struct dcn20_hubbub *hubbub,
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 21/25] drm/amd/display: Add missing HBM support and raise Vega20's uclk.

2019-09-10 Thread sunpeng.li
From: Zhan Liu 

[Why]
When more than 2 displays are connected to the graphics card,
only the minimum memory clock is needed. However, when more
displays are connected, the minimum memory clock is not
sufficient enough to support the overwhelming bandwidth.
System will hang under this circumstance.

Also, the old code didn't address HBM cards, which has 2
pseudo channels. We need to add the HBM part here.

[How]
When graphics card connects to 2 or more displays,
switch to high memory clock. Also, choose memory
multiplier based on whether its regular DRAM or HBM.

Signed-off-by: Zhan Liu 
Reviewed-by: Roman Li 
Acked-by: Leo Li 
---
 .../display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
index ee32d2c19305..36277bca0326 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
@@ -174,6 +174,10 @@ void dce11_pplib_apply_display_requirements(
struct dc_state *context)
 {
struct dm_pp_display_configuration *pp_display_cfg = 
&context->pp_display_cfg;
+   int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
+
+   if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
+   memory_type_multiplier = MEMORY_TYPE_HBM;
 
pp_display_cfg->all_displays_in_sync =
context->bw_ctx.bw.dce.all_displays_in_sync;
@@ -186,8 +190,18 @@ void dce11_pplib_apply_display_requirements(
pp_display_cfg->cpu_pstate_separation_time =
context->bw_ctx.bw.dce.blackout_recovery_time_us;
 
-   pp_display_cfg->min_memory_clock_khz = context->bw_ctx.bw.dce.yclk_khz
-   / MEMORY_TYPE_MULTIPLIER_CZ;
+   /*
+* TODO: determine whether the bandwidth has reached memory's limitation
+* , then change minimum memory clock based on real-time bandwidth
+* limitation.
+*/
+   if (ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && 
(context->stream_count >= 2)) {
+   pp_display_cfg->min_memory_clock_khz = 
max(pp_display_cfg->min_memory_clock_khz,
+   (uint32_t) (dc->bw_vbios->high_yclk.value / 
memory_type_multiplier / 1));
+   } else {
+   pp_display_cfg->min_memory_clock_khz = 
context->bw_ctx.bw.dce.yclk_khz
+   / memory_type_multiplier;
+   }
 
pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
dc,
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 05/25] drm/amd/display: Replace for loop w/ function call

2019-09-10 Thread sunpeng.li
From: Wesley Chalmers 

[WHY]
A function to adjust DPP clocks with DTO already exists; function code
is identical to the code replaced here

Signed-off-by: Wesley Chalmers 
Reviewed-by: Charlene Liu 
Acked-by: Leo Li 
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 25 ++-
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 3e8ac303bd52..f1df32664414 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -196,7 +196,6 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
bool enter_display_off = false;
struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
bool force_reset = false;
-   int i;
 
if (dc->work_arounds.skip_clock_update)
return;
@@ -278,34 +277,14 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,

request_voltage_and_program_global_dpp_clk(clk_mgr_base, 
new_clocks->dppclk_khz);
 
// Then raise any dividers that need raising
-   for (i = 0; i < 
clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
-   int dpp_inst, dppclk_khz;
-
-   if (!context->res_ctx.pipe_ctx[i].plane_state)
-   continue;
-
-   dpp_inst = 
context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
-   dppclk_khz = 
context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
-
-   
clk_mgr->dccg->funcs->update_dpp_dto(clk_mgr->dccg, dpp_inst, dppclk_khz, true);
-   }
+   dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
} else {
// For post-programming, we can lower ref clk if 
needed, and unconditionally set all the DTOs
 
if (new_clocks->dppclk_khz < 
clk_mgr_base->clks.dppclk_khz)

request_voltage_and_program_global_dpp_clk(clk_mgr_base, 
new_clocks->dppclk_khz);
+   dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
 
-   for (i = 0; i < 
clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
-   int dpp_inst, dppclk_khz;
-
-   if (!context->res_ctx.pipe_ctx[i].plane_state)
-   continue;
-
-   dpp_inst = 
context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
-   dppclk_khz = 
context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
-
-   
clk_mgr->dccg->funcs->update_dpp_dto(clk_mgr->dccg, dpp_inst, dppclk_khz, 
false);
-   }
}
}
if (update_dispclk &&
-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 25/25] drm/amd/display: Improve LFC behaviour

2019-09-10 Thread sunpeng.li
From: Aric Cyr 

[Why]
There can be some unsynchronized frames when entering/exiting
LFC.  This may cause tearing or stuttering at such transitions.

[How]
Add a enter/exit margin to algorithm to smoothly transition into
and out of LFC without desynchronizing frames.

Signed-off-by: Aric Cyr 
Reviewed-by: Reza Amini 
Acked-by: Leo Li 
Acked-by: Sivapiriyan Kumarasamy 
---
 .../amd/display/modules/freesync/freesync.c   | 32 +++
 .../amd/display/modules/inc/mod_freesync.h|  1 +
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 107d81ea689b..5e5ce9e5eab7 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -35,8 +35,8 @@
 #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)
 /* Number of elements in the render times cache array */
 #define RENDER_TIMES_MAX_COUNT 10
-/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
-#define BTR_EXIT_MARGIN 2000
+/* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower 
limit) */
+#define BTR_MAX_MARGIN 2500
 /* Threshold to change BTR multiplier (to avoid frequent changes) */
 #define BTR_DRIFT_MARGIN 2000
 /*Threshold to exit fixed refresh rate*/
@@ -248,24 +248,22 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
unsigned int delta_from_mid_point_in_us_1 = 0x;
unsigned int delta_from_mid_point_in_us_2 = 0x;
unsigned int frames_to_insert = 0;
-   unsigned int min_frame_duration_in_ns = 0;
-   unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us;
unsigned int delta_from_mid_point_delta_in_us;
-
-   min_frame_duration_in_ns = ((unsigned int) (div64_u64(
-   (10ULL * 100),
-   in_out_vrr->max_refresh_in_uhz)));
+   unsigned int max_render_time_in_us =
+   in_out_vrr->max_duration_in_us - 
in_out_vrr->btr.margin_in_us;
 
/* Program BTR */
-   if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) {
+   if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < 
max_render_time_in_us) {
/* Exit Below the Range */
if (in_out_vrr->btr.btr_active) {
in_out_vrr->btr.frame_counter = 0;
in_out_vrr->btr.btr_active = false;
}
-   } else if (last_render_time_in_us > max_render_time_in_us) {
+   } else if (last_render_time_in_us > (max_render_time_in_us + 
in_out_vrr->btr.margin_in_us / 2)) {
/* Enter Below the Range */
-   in_out_vrr->btr.btr_active = true;
+   if (!in_out_vrr->btr.btr_active) {
+   in_out_vrr->btr.btr_active = true;
+   }
}
 
/* BTR set to "not active" so disengage */
@@ -321,7 +319,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
/* Choose number of frames to insert based on how close it
 * can get to the mid point of the variable range.
 */
-   if (delta_from_mid_point_in_us_1 < 
delta_from_mid_point_in_us_2) {
+   if ((frame_time_in_us / mid_point_frames_ceil) > 
in_out_vrr->min_duration_in_us &&
+   (delta_from_mid_point_in_us_1 < 
delta_from_mid_point_in_us_2 ||
+   mid_point_frames_floor < 2)) {
frames_to_insert = mid_point_frames_ceil;
delta_from_mid_point_delta_in_us = 
delta_from_mid_point_in_us_2 -
delta_from_mid_point_in_us_1;
@@ -337,7 +337,7 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
if (in_out_vrr->btr.frames_to_insert != 0 &&
delta_from_mid_point_delta_in_us < 
BTR_DRIFT_MARGIN) {
if (((last_render_time_in_us / 
in_out_vrr->btr.frames_to_insert) <
-   in_out_vrr->max_duration_in_us) &&
+   max_render_time_in_us) &&
((last_render_time_in_us / 
in_out_vrr->btr.frames_to_insert) >
in_out_vrr->min_duration_in_us))
frames_to_insert = 
in_out_vrr->btr.frames_to_insert;
@@ -786,6 +786,11 @@ void mod_freesync_build_vrr_params(struct mod_freesync 
*mod_freesync,
refresh_range = in_out_vrr->max_refresh_in_uhz -
in_out_vrr->min_refresh_in_uhz;
 
+   in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us -
+   2 * in_out_vrr->min_duration_in_us;
+   i

[PATCH 00/25] DC Patches 09 Sep 2019

2019-09-10 Thread sunpeng.li
From: Leo Li 

Summary of change:

* Fix pipe split with DSC on high bandwidth timings (8k@60, 4k@144)
* Improve freesync low frame rate compensation (frame doubling) behavior
* Update ABM parameters, limit minimum adjustment
* Misc. refactors and fixes


Anthony Koo (1):
  drm/amd/display: set minimum abm backlight level

Aric Cyr (4):
  drm/amd/display: 3.2.50
  drm/amd/display: 3.4.51
  drm/amd/display: 3.4.51.1
  drm/amd/display: Improve LFC behaviour

Dmytro Laktyushkin (5):
  drm/amd/display: add additional flag consideration for surface update
  drm/amd/display: add vtg update after global sync update
  drm/amd/display: fix global sync param extraction indexing
  drm/amd/display: update odm mode validation to be in line with policy
  drm/amd/display: Add detile buffer size for DCN20

Ilya Bakoulin (1):
  drm/amd/display: Fix HUBP secondary viewport programming

Josip Pavic (1):
  drm/amd/display: define parameters for abm 2.3

Julian Parkin (1):
  drm/amd/display: Separate hardware initialization from creation

Lewis Huang (1):
  drm/amd/display: fix i2c wtire mot incorrect issue

Martin Leung (2):
  drm/amd/display: enable single dp seamless boot
  drm/amd/display: fix use of uninitialized variable

Martin Tsai (1):
  drm/amd/display: Handle virtual signal type in disable_link()

Mikita Lipski (1):
  drm/amd/display: Rebuild mapped resources after pipe split

Nikola Cornij (1):
  drm/amd/display: Set number of pipes to 1 if the second pipe was
disabled

Stylon Wang (1):
  drm/amd/display: Add debugfs entry to force YUV420 output

Wesley Chalmers (4):
  drm/amd/display: Replace for loop w/ function call
  drm/amd/display: Do not double-buffer DTO adjustments
  drm/amd/display: Revert fixup DPP programming sequence
  drm/amd/display: Optimize clocks on clock change

Zhan Liu (1):
  drm/amd/display: Add missing HBM support and raise Vega20's uclk.

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  12 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |  31 
 .../dc/clk_mgr/dce110/dce110_clk_mgr.c|  18 ++-
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 132 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  38 ++---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  63 ++---
 .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |   4 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  26 ++--
 drivers/gpu/drm/amd/display/dc/dc.h   |  12 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c |   8 ++
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h |  12 ++
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   3 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c |  52 +--
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h |   2 +-
 .../drm/amd/display/dc/dcn20/dcn20_hubbub.c   |  12 +-
 .../drm/amd/display/dc/dcn20/dcn20_hubbub.h   |   1 +
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c|  11 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c |   4 +
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |  29 +---
 .../dc/dml/dcn20/display_mode_vba_20v2.c  |   9 +-
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   1 +
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |  10 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |   3 +-
 .../amd/display/modules/freesync/freesync.c   |  32 +++--
 .../amd/display/modules/inc/mod_freesync.h|   1 +
 .../amd/display/modules/power/power_helpers.c |  93 ++--
 .../amd/display/modules/power/power_helpers.h |   1 +
 28 files changed, 315 insertions(+), 306 deletions(-)

-- 
2.22.0

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH RFC v4 00/16] new cgroup controller for gpu/drm subsystem

2019-09-10 Thread Tejun Heo
Hello, Michal.

On Tue, Sep 10, 2019 at 01:54:48PM +0200, Michal Hocko wrote:
> > So, while it'd great to have shrinkers in the longer term, it's not a
> > strict requirement to be accounted in memcg.  It already accounts a
> > lot of memory which isn't reclaimable (a lot of slabs and socket
> > buffer).
> 
> Yeah, having a shrinker is preferred but the memory should better be
> reclaimable in some form. If not by any other means then at least bound
> to a user process context so that it goes away with a task being killed
> by the OOM killer. If that is not the case then we cannot really charge
> it because then the memcg controller is of no use. We can tolerate it to
> some degree if the amount of memory charged like that is negligible to
> the overall size. But from the discussion it seems that these buffers
> are really large.

Yeah, oom kills should be able to reduce the usage; however, please
note that tmpfs, among other things, can already escape this
restriction and we can have cgroups which are over max and empty.
It's obviously not ideal but the system doesn't melt down from it
either.

Thanks.

-- 
tejun
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH RFC v4 00/16] new cgroup controller for gpu/drm subsystem

2019-09-10 Thread Michal Hocko
On Tue 10-09-19 09:03:29, Tejun Heo wrote:
> Hello, Michal.
> 
> On Tue, Sep 10, 2019 at 01:54:48PM +0200, Michal Hocko wrote:
> > > So, while it'd great to have shrinkers in the longer term, it's not a
> > > strict requirement to be accounted in memcg.  It already accounts a
> > > lot of memory which isn't reclaimable (a lot of slabs and socket
> > > buffer).
> > 
> > Yeah, having a shrinker is preferred but the memory should better be
> > reclaimable in some form. If not by any other means then at least bound
> > to a user process context so that it goes away with a task being killed
> > by the OOM killer. If that is not the case then we cannot really charge
> > it because then the memcg controller is of no use. We can tolerate it to
> > some degree if the amount of memory charged like that is negligible to
> > the overall size. But from the discussion it seems that these buffers
> > are really large.
> 
> Yeah, oom kills should be able to reduce the usage; however, please
> note that tmpfs, among other things, can already escape this
> restriction and we can have cgroups which are over max and empty.
> It's obviously not ideal but the system doesn't melt down from it
> either.

Right, and that is a reason why an access to tmpfs should be restricted
when containing a workload by memcg. My understanding of this particular
feature is that memcg should be the primary containment method and
that's why I brought this up.

-- 
Michal Hocko
SUSE Labs
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 08/20] drm/amdgpu: psp HDCP init

2019-09-10 Thread Bhawanpreet Lakha
This patch adds
-Loading the firmware
-The functions and definitions for communication with the firmware

v2: Fix formatting

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 189 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  17 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   3 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  33 +++-
 4 files changed, 240 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index f90a0cd12827..e75d164ea85b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -766,6 +766,181 @@ static int psp_ras_initialize(struct psp_context *psp)
 }
 // ras end
 
+// HDCP start
+static void psp_prep_hdcp_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+ uint64_t hdcp_ta_mc,
+ uint64_t hdcp_mc_shared,
+ uint32_t hdcp_ta_size,
+ uint32_t shared_size)
+{
+   cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
+   cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(hdcp_ta_mc);
+   cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(hdcp_ta_mc);
+   cmd->cmd.cmd_load_ta.app_len = hdcp_ta_size;
+
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo =
+   lower_32_bits(hdcp_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi =
+   upper_32_bits(hdcp_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
+}
+
+static int psp_hdcp_init_shared_buf(struct psp_context *psp)
+{
+   int ret;
+
+   /*
+* Allocate 16k memory aligned to 4k from Frame Buffer (local
+* physical) for hdcp ta <-> Driver
+*/
+   ret = amdgpu_bo_create_kernel(psp->adev, PSP_HDCP_SHARED_MEM_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->hdcp_context.hdcp_shared_bo,
+ &psp->hdcp_context.hdcp_shared_mc_addr,
+ &psp->hdcp_context.hdcp_shared_buf);
+
+   return ret;
+}
+
+static int psp_hdcp_load(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   memset(psp->fw_pri_buf, 0, PSP_1_MEG);
+   memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr,
+  psp->ta_hdcp_ucode_size);
+
+   psp_prep_hdcp_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
+ psp->hdcp_context.hdcp_shared_mc_addr,
+ psp->ta_hdcp_ucode_size,
+ PSP_HDCP_SHARED_MEM_SIZE);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   if (!ret) {
+   psp->hdcp_context.hdcp_initialized = 1;
+   psp->hdcp_context.session_id = cmd->resp.session_id;
+   }
+
+   kfree(cmd);
+
+   return ret;
+}
+static int psp_hdcp_initialize(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->hdcp_context.hdcp_initialized) {
+   ret = psp_hdcp_init_shared_buf(psp);
+   if (ret)
+   return ret;
+   }
+
+   ret = psp_hdcp_load(psp);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+static void psp_prep_hdcp_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+   uint32_t hdcp_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA;
+   cmd->cmd.cmd_unload_ta.session_id = hdcp_session_id;
+}
+
+static int psp_hdcp_unload(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the unloading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   psp_prep_hdcp_ta_unload_cmd_buf(cmd, psp->hdcp_context.session_id);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static void psp_prep_hdcp_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+   uint32_t ta_cmd_id,
+   uint32_t hdcp_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
+   cmd->cmd.cmd_invoke_cmd.session_id = hdcp_session_id;
+   cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
+   /* Note: cmd_invoke_cmd.buf is not used for now */
+}
+
+int psp_hdcp_invoke(st

[PATCH 02/20] drm: generic fn converting be24 to cpu and vice versa

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

Existing functions for converting a 3bytes(be24) of big endian value
into u32 of little endian and vice versa are renamed as

s/drm_hdcp2_seq_num_to_u32/drm_hdcp_be24_to_cpu
s/drm_hdcp2_u32_to_seq_num/drm_hdcp_cpu_to_be24

Signed-off-by: Ramalingam C 
Suggested-by: Daniel Vetter 
cc: Tomas Winkler 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-4-ramalinga...@intel.com
---
 drivers/gpu/drm/i915/intel_hdcp.c | 5 +++--
 drivers/misc/mei/hdcp/mei_hdcp.c  | 2 +-
 include/drm/drm_hdcp.h| 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
b/drivers/gpu/drm/i915/intel_hdcp.c
index 99b007169c49..536cddc74d22 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1306,7 +1306,7 @@ int hdcp2_propagate_stream_management_info(struct 
intel_connector *connector)
 
/* Prepare RepeaterAuth_Stream_Manage msg */
msgs.stream_manage.msg_id = HDCP_2_2_REP_STREAM_MANAGE;
-   drm_hdcp2_u32_to_seq_num(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
+   drm_hdcp_cpu_to_be24(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
 
/* K no of streams is fixed as 1. Stored as big-endian. */
msgs.stream_manage.k = cpu_to_be16(1);
@@ -1371,7 +1371,8 @@ int hdcp2_authenticate_repeater_topology(struct 
intel_connector *connector)
}
 
/* Converting and Storing the seq_num_v to local variable as DWORD */
-   seq_num_v = drm_hdcp2_seq_num_to_u32(msgs.recvid_list.seq_num_v);
+   seq_num_v =
+   drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v);
 
if (seq_num_v < hdcp->seq_num_v) {
/* Roll over of the seq_num_v from repeater. Reauthenticate. */
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index b07000202d4a..417865129407 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -576,7 +576,7 @@ static int mei_hdcp_verify_mprime(struct device *dev,
 
memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
   HDCP_2_2_MPRIME_LEN);
-   drm_hdcp2_u32_to_seq_num(verify_mprime_in.seq_num_m, data->seq_num_m);
+   drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
memcpy(verify_mprime_in.streams, data->streams,
   (data->k * sizeof(struct hdcp2_streamid_type)));
 
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index f243408ecf26..1cc66df05a43 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -252,13 +252,13 @@ struct hdcp2_rep_stream_ready {
  * host format and back
  */
 static inline
-u32 drm_hdcp2_seq_num_to_u32(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN])
+u32 drm_hdcp_be24_to_cpu(const u8 seq_num[HDCP_2_2_SEQ_NUM_LEN])
 {
return (u32)(seq_num[2] | seq_num[1] << 8 | seq_num[0] << 16);
 }
 
 static inline
-void drm_hdcp2_u32_to_seq_num(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
+void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
 {
seq_num[0] = val >> 16;
seq_num[1] = val >> 8;
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 13/20] drm/amd/display: Create amdgpu_dm_hdcp

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to interact with the hdcp module from the DM, the module
has to be interacted with in terms of events

[How]
Create the files needed for linux hdcp. These files manage the events
needed for the dm to interact with the hdcp module.

We use the kernel work queue to process the events needed for
the module

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/Makefile|   4 +
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 241 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|  61 +
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile 
b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index 94911871eb9b..9a3b7bf8ab0b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -31,6 +31,10 @@ ifneq ($(CONFIG_DRM_AMD_DC),)
 AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o
 endif
 
+ifdef CONFIG_DRM_AMD_DC_HDCP
+AMDGPUDM += amdgpu_dm_hdcp.o
+endif
+
 ifneq ($(CONFIG_DEBUG_FS),)
 AMDGPUDM += amdgpu_dm_crc.o amdgpu_dm_debugfs.o
 endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
new file mode 100644
index ..004b6e8e9ed5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "amdgpu_dm_hdcp.h"
+#include "amdgpu.h"
+#include "amdgpu_dm.h"
+
+static void process_output(struct hdcp_workqueue *hdcp_work)
+{
+   struct mod_hdcp_output output = hdcp_work->output;
+
+   if (output.callback_stop)
+   cancel_delayed_work(&hdcp_work->callback_dwork);
+
+   if (output.callback_needed)
+   schedule_delayed_work(&hdcp_work->callback_dwork,
+ msecs_to_jiffies(output.callback_delay));
+
+   if (output.watchdog_timer_stop)
+   cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
+
+   if (output.watchdog_timer_needed)
+   schedule_delayed_work(&hdcp_work->watchdog_timer_dwork,
+ 
msecs_to_jiffies(output.watchdog_timer_delay));
+
+}
+
+void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+   struct mod_hdcp_display *display = &hdcp_work[link_index].display;
+   struct mod_hdcp_link *link = &hdcp_work[link_index].link;
+
+   mutex_lock(&hdcp_w->mutex);
+
+   mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
+
+   process_output(hdcp_w);
+
+   mutex_unlock(&hdcp_w->mutex);
+
+}
+
+void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index,  unsigned int display_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+   mutex_lock(&hdcp_w->mutex);
+
+   mod_hdcp_remove_display(&hdcp_w->hdcp, display_index, &hdcp_w->output);
+
+   process_output(hdcp_w);
+
+   mutex_unlock(&hdcp_w->mutex);
+
+}
+
+void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+   mutex_lock(&hdcp_w->mutex);
+
+   mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
+
+   process_output(hdcp_w);
+
+   mutex_unlock(&hdcp_w->mutex);
+}
+
+void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+   schedule_work(&hdcp_w->cpirq_work);
+}
+
+
+
+
+static void eve

[PATCH 04/20] drm/hdcp: gathering hdcp related code into drm_hdcp.c

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

Considering the significant size of hdcp related code in drm, all
hdcp related codes are moved into separate file called drm_hdcp.c.

v2:
  Rebased.
v2:
  Rebased.

Signed-off-by: Ramalingam C 
Suggested-by: Daniel Vetter 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-7-ramalinga...@intel.com
---
 drivers/gpu/drm/drm_connector.c | 44 --
 drivers/gpu/drm/drm_hdcp.c  | 47 +
 include/drm/drm_connector.h |  2 --
 include/drm/drm_hdcp.h  |  3 +++
 4 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 0490c204122d..11fcd25bc640 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -823,13 +823,6 @@ static const struct drm_prop_enum_list 
drm_tv_subconnector_enum_list[] = {
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
 drm_tv_subconnector_enum_list)
 
-static struct drm_prop_enum_list drm_cp_enum_list[] = {
-   { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
-   { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
-   { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
-};
-DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
-
 static const struct drm_prop_enum_list hdmi_colorspaces[] = {
/* For Default case, driver will set the colorspace */
{ DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
@@ -1509,43 +1502,6 @@ int drm_connector_attach_scaling_mode_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
 
-/**
- * drm_connector_attach_content_protection_property - attach content protection
- * property
- *
- * @connector: connector to attach CP property on.
- *
- * This is used to add support for content protection on select connectors.
- * Content Protection is intentionally vague to allow for different underlying
- * technologies, however it is most implemented by HDCP.
- *
- * The content protection will be set to 
&drm_connector_state.content_protection
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
-int drm_connector_attach_content_protection_property(
-   struct drm_connector *connector)
-{
-   struct drm_device *dev = connector->dev;
-   struct drm_property *prop =
-   dev->mode_config.content_protection_property;
-
-   if (!prop)
-   prop = drm_property_create_enum(dev, 0, "Content Protection",
-   drm_cp_enum_list,
-   ARRAY_SIZE(drm_cp_enum_list));
-   if (!prop)
-   return -ENOMEM;
-
-   drm_object_attach_property(&connector->base, prop,
-  DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-   dev->mode_config.content_protection_property = prop;
-
-   return 0;
-}
-EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
-
 /**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 5e5409505c31..0da7b3718bad 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -17,6 +17,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 struct hdcp_srm {
u32 revoked_ksv_cnt;
@@ -331,3 +334,47 @@ void drm_teardown_hdcp_srm(struct class *drm_class)
kfree(srm_data);
}
 }
+
+static struct drm_prop_enum_list drm_cp_enum_list[] = {
+   { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+   { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+   { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
+
+/**
+ * drm_connector_attach_content_protection_property - attach content protection
+ * property
+ *
+ * @connector: connector to attach CP property on.
+ *
+ * This is used to add support for content protection on select connectors.
+ * Content Protection is intentionally vague to allow for different underlying
+ * technologies, however it is most implemented by HDCP.
+ *
+ * The content protection will be set to 
&drm_connector_state.content_protection
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_content_protection_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop =
+   dev->mode_config.content_protection_property;
+
+   if (!prop)
+   prop = drm_property_create_enum(dev, 0, "Content Protection",
+   drm_cp_enum_list,
+   ARRAY_SIZE(dr

[PATCH 05/20] drm: Add Content protection type property

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

This patch adds a DRM ENUM property to the selected connectors.
This property is used for mentioning the protected content's type
from userspace to kernel HDCP authentication.

Type of the stream is decided by the protected content providers.
Type 0 content can be rendered on any HDCP protected display wires.
But Type 1 content can be rendered only on HDCP2.2 protected paths.

So when a userspace sets this property to Type 1 and starts the HDCP
enable, kernel will honour it only if HDCP2.2 authentication is through
for type 1. Else HDCP enable will be failed.

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  cp_content_type is replaced with content_protection_type [daniel]
  check at atomic_set_property is removed [Maarten]
v3:
  %s/content_protection_type/hdcp_content_type [Pekka]
v4:
  property is created for the first requested connector and then reused.
[Danvet]
v5:
  kernel doc nits addressed [Daniel]
  Rebased as part of patch reordering.
v6:
  Kernel docs are modified [pekka]
v7:
  More details in Kernel docs. [pekka]
v8:
  Few more clarification into kernel doc of content type [pekka]
v9:
  Small fixes in coding style.
v10:
  Moving DRM_MODE_HDCP_CONTENT_TYPEx definition to drm_hdcp.h [pekka]

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Acked-by: Pekka Paalanen 
Acked-by: Jani Nikula 
Link: https://patchwork.freedesktop.org/patch/320957/?series=57232&rev=14
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 +++
 drivers/gpu/drm/drm_connector.c   | 51 +++
 drivers/gpu/drm/drm_hdcp.c| 36 +-
 drivers/gpu/drm/i915/intel_hdcp.c |  4 ++-
 include/drm/drm_connector.h   |  7 +
 include/drm/drm_hdcp.h|  7 -
 include/drm/drm_mode_config.h |  6 
 7 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 4131e669785a..a85f3ccfe699 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
return -EINVAL;
}
state->content_protection = val;
+   } else if (property == config->hdcp_content_type_property) {
+   state->hdcp_content_type = val;
} else if (property == connector->colorspace_property) {
state->colorspace = val;
} else if (property == config->writeback_fb_id_property) {
@@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->scaling_mode;
} else if (property == config->content_protection_property) {
*val = state->content_protection;
+   } else if (property == config->hdcp_content_type_property) {
+   *val = state->hdcp_content_type;
} else if (property == config->writeback_fb_id_property) {
/* Writeback framebuffer is one-shot, write and forget */
*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 11fcd25bc640..3b0910b36ef5 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -956,6 +956,57 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] 
= {
  *   is no longer protected and userspace should take appropriate action
  *   (whatever that might be).
  *
+ * HDCP Content Type:
+ * This Enum property is used by the userspace to declare the content type
+ * of the display stream, to kernel. Here display stream stands for any
+ * display content that userspace intended to display through HDCP
+ * encryption.
+ *
+ * Content Type of a stream is decided by the owner of the stream, as
+ * "HDCP Type0" or "HDCP Type1".
+ *
+ * The value of the property can be one of the below:
+ *   - "HDCP Type0": DRM_MODE_HDCP_CONTENT_TYPE0 = 0
+ *   - "HDCP Type1": DRM_MODE_HDCP_CONTENT_TYPE1 = 1
+ *
+ * When kernel starts the HDCP authentication (see "Content Protection"
+ * for details), it uses the content type in "HDCP Content Type"
+ * for performing the HDCP authentication with the display sink.
+ *
+ * Please note in HDCP spec versions, a link can be authenticated with
+ * HDCP 2.2 for Content Type 0/Content Type 1. Where as a link can be
+ * authenticated with HDCP1.4 only for Content Type 0(though it is implicit
+ * in nature. As there is no reference for Content Type in HDCP1.4).
+ *
+ * HDCP2.2 authentication protocol itself takes the "Content Type" as a
+ * parameter, which is a input for the DP HDCP2.2 encryption algo.
+ *
+ * In case of Type 0 content protection request, kernel driver can choose
+ * either of HDCP spec ver

[PATCH 15/20] drm/amd/display: Initialize HDCP work queue

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need this to enable HDCP on linux, as we need events to interact
with the hdcp module

[How]
Add work queue to display manager and handle the creation and destruction
of the queue

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 ++
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c1031121ee8a..2cc95ab0b645 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -37,6 +37,9 @@
 #include "amdgpu_ucode.h"
 #include "atom.h"
 #include "amdgpu_dm.h"
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+#include "amdgpu_dm_hdcp.h"
+#endif
 #include "amdgpu_pm.h"
 
 #include "amd_shared.h"
@@ -644,11 +647,18 @@ void amdgpu_dm_audio_eld_notify(struct amdgpu_device 
*adev, int pin)
 static int amdgpu_dm_init(struct amdgpu_device *adev)
 {
struct dc_init_data init_data;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct dc_callback_init init_params;
+#endif
+
adev->dm.ddev = adev->ddev;
adev->dm.adev = adev;
 
/* Zero all the fields */
memset(&init_data, 0, sizeof(init_data));
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   memset(&init_params, 0, sizeof(init_params));
+#endif
 
mutex_init(&adev->dm.dc_lock);
mutex_init(&adev->dm.audio_lock);
@@ -721,6 +731,16 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 
amdgpu_dm_init_color_mod();
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   adev->dm.hdcp_workqueue = hdcp_create_workqueue(&adev->psp, 
&init_params.cp_psp, adev->dm.dc);
+
+   if (!adev->dm.hdcp_workqueue)
+   DRM_ERROR("amdgpu: failed to initialize hdcp_workqueue.\n");
+   else
+   DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done %p.\n", 
adev->dm.hdcp_workqueue);
+
+   dc_init_callbacks(adev->dm.dc, &init_params);
+#endif
if (amdgpu_dm_initialize_drm_device(adev)) {
DRM_ERROR(
"amdgpu: failed to initialize sw for display support.\n");
@@ -762,6 +782,16 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
 
amdgpu_dm_destroy_drm_device(&adev->dm);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   if (adev->dm.hdcp_workqueue) {
+   hdcp_destroy(adev->dm.hdcp_workqueue);
+   adev->dm.hdcp_workqueue = NULL;
+   }
+
+   if (adev->dm.dc)
+   dc_deinit_callbacks(adev->dm.dc);
+#endif
+
/* DC Destroy TODO: Replace destroy DAL */
if (adev->dm.dc)
dc_destroy(&adev->dm.dc);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index cbd6608f58e6..7a34eca12dab 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -222,6 +222,9 @@ struct amdgpu_display_manager {
struct amdgpu_dm_backlight_caps backlight_caps;
 
struct mod_freesync *freesync_module;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct hdcp_workqueue *hdcp_workqueue;
+#endif
 
struct drm_atomic_state *cached_state;
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 03/20] drm: revocation check at drm subsystem

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

On every hdcp revocation check request SRM is read from fw file
/lib/firmware/display_hdcp_srm.bin

SRM table is parsed and stored at drm_hdcp.c, with functions exported
for the services for revocation check from drivers (which
implements the HDCP authentication)

This patch handles the HDCP1.4 and 2.2 versions of SRM table.

v2:
  moved the uAPI to request_firmware_direct() [Daniel]
v3:
  kdoc added. [Daniel]
  srm_header unified and bit field definitions are removed. [Daniel]
  locking improved. [Daniel]
  vrl length violation is fixed. [Daniel]
v4:
  s/__swab16/be16_to_cpu [Daniel]
  be24_to_cpu is done through a global func [Daniel]
  Unused variables are removed. [Daniel]
  unchecked return values are dropped from static funcs [Daniel]

Signed-off-by: Ramalingam C 
Acked-by: Satyeshwar Singh 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-5-ramalinga...@intel.com
---
 Documentation/gpu/drm-kms-helpers.rst |   6 +
 drivers/gpu/drm/Makefile  |   2 +-
 drivers/gpu/drm/drm_hdcp.c| 333 ++
 drivers/gpu/drm/drm_internal.h|   4 +
 drivers/gpu/drm/drm_sysfs.c   |   2 +
 include/drm/drm_hdcp.h|  24 ++
 6 files changed, 370 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_hdcp.c

diff --git a/Documentation/gpu/drm-kms-helpers.rst 
b/Documentation/gpu/drm-kms-helpers.rst
index 14102ae035dc..0fe726a6ee67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -181,6 +181,12 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
:export:
 
+HDCP Helper Functions Reference
+===
+
+.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
+   :export:
+
 Display Port Helper Functions Reference
 ===
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f204830669e2..7fa09ea00ffd 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,7 @@ drm-y   :=drm_auth.o drm_cache.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-   drm_atomic_uapi.o
+   drm_atomic_uapi.o drm_hdcp.o
 
 drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o 
drm_dma.o drm_scatter.o drm_lock.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
new file mode 100644
index ..5e5409505c31
--- /dev/null
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Intel Corporation.
+ *
+ * Authors:
+ * Ramalingam C 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+struct hdcp_srm {
+   u32 revoked_ksv_cnt;
+   u8 *revoked_ksv_list;
+
+   /* Mutex to protect above struct member */
+   struct mutex mutex;
+} *srm_data;
+
+static inline void drm_hdcp_print_ksv(const u8 *ksv)
+{
+   DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
+ ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]);
+}
+
+static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32 vrls_length)
+{
+   u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
+
+   while (parsed_bytes < vrls_length) {
+   vrl_ksv_cnt = *buf;
+   ksv_count += vrl_ksv_cnt;
+
+   vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
+   buf += vrl_sz;
+   parsed_bytes += vrl_sz;
+   }
+
+   /*
+* When vrls are not valid, ksvs are not considered.
+* Hence SRM will be discarded.
+*/
+   if (parsed_bytes != vrls_length)
+   ksv_count = 0;
+
+   return ksv_count;
+}
+
+static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8 *revoked_ksv_list,
+u32 vrls_length)
+{
+   u32 parsed_bytes = 0, ksv_count = 0;
+   u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
+
+   do {
+   vrl_ksv_cnt = *buf;
+   vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
+
+   buf++;
+
+   DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
+ vrl_ksv_cnt);
+   memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
+
+   ksv_count += vrl_ksv_cnt;
+   revoked_ksv_list += vrl_ksv_sz;
+   buf += vrl_ksv_sz;
+
+   parsed_bytes += (vrl_ksv_sz + 1);
+   } while (parsed_bytes < vrls_length);
+
+   return ksv_count;
+}
+
+static inline u32 get_vrl_length(const u8 *buf)
+{
+   return drm_hdcp_be24_to_cpu(buf);
+}
+
+static int drm_hdcp_parse_hdcp1_s

[PATCH 01/20] drm: move content protection property to mode_config

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

Content protection property is created once and stored in
drm_mode_config. And attached to all HDCP capable connectors.

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-2-ramalinga...@intel.com
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 ++--
 drivers/gpu/drm/drm_connector.c   | 13 +++--
 include/drm/drm_connector.h   |  6 --
 include/drm/drm_mode_config.h |  6 ++
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 428d82662dc4..4131e669785a 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -732,7 +732,7 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->content_type = val;
} else if (property == connector->scaling_mode_property) {
state->scaling_mode = val;
-   } else if (property == connector->content_protection_property) {
+   } else if (property == config->content_protection_property) {
if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
return -EINVAL;
@@ -814,7 +814,7 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->colorspace;
} else if (property == connector->scaling_mode_property) {
*val = state->scaling_mode;
-   } else if (property == connector->content_protection_property) {
+   } else if (property == config->content_protection_property) {
*val = state->content_protection;
} else if (property == config->writeback_fb_id_property) {
/* Writeback framebuffer is one-shot, write and forget */
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b34c3d38bf15..0490c204122d 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1528,18 +1528,19 @@ int drm_connector_attach_content_protection_property(
struct drm_connector *connector)
 {
struct drm_device *dev = connector->dev;
-   struct drm_property *prop;
+   struct drm_property *prop =
+   dev->mode_config.content_protection_property;
 
-   prop = drm_property_create_enum(dev, 0, "Content Protection",
-   drm_cp_enum_list,
-   ARRAY_SIZE(drm_cp_enum_list));
+   if (!prop)
+   prop = drm_property_create_enum(dev, 0, "Content Protection",
+   drm_cp_enum_list,
+   ARRAY_SIZE(drm_cp_enum_list));
if (!prop)
return -ENOMEM;
 
drm_object_attach_property(&connector->base, prop,
   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-
-   connector->content_protection_property = prop;
+   dev->mode_config.content_protection_property = prop;
 
return 0;
 }
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 02a131202add..5e41942e5679 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1061,12 +1061,6 @@ struct drm_connector {
 */
struct drm_property *vrr_capable_property;
 
-   /**
-* @content_protection_property: DRM ENUM property for content
-* protection. See drm_connector_attach_content_protection_property().
-*/
-   struct drm_property *content_protection_property;
-
/**
 * @colorspace_property: Connector property to set the suitable
 * colorspace supported by the sink.
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 7f60e8eb269a..5764ee3c7453 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -836,6 +836,12 @@ struct drm_mode_config {
 */
struct drm_property *writeback_out_fence_ptr_property;
 
+   /**
+* @content_protection_property: DRM ENUM property for content
+* protection. See drm_connector_attach_content_protection_property().
+*/
+   struct drm_property *content_protection_property;
+
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 17/20] drm/amd/display: handle DP cpirq

2019-09-10 Thread Bhawanpreet Lakha
[Why]
This is needed for DP as DP can send us info using irq.

[How]
Check if irq bit is set on short pulse and call the
function that handles cpirq in amdgpu_dm_hdcp

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 591b8ab9d4ad..a1895b873ef2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1617,6 +1617,12 @@ static void handle_hpd_rx_irq(void *param)
struct dc_link *dc_link = aconnector->dc_link;
bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   union hpd_irq_data hpd_irq_data;
+   struct amdgpu_device *adev = dev->dev_private;
+
+   memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
+#endif
 
/*
 * TODO:Temporary add mutex to protect hpd interrupt not have a gpio
@@ -1626,7 +1632,12 @@ static void handle_hpd_rx_irq(void *param)
if (dc_link->type != dc_connection_mst_branch)
mutex_lock(&aconnector->hpd_lock);
 
+
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   if (dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL) &&
+#else
if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
+#endif
!is_mst_root_connector) {
/* Downstream Port status changed. */
if (!dc_link_detect_sink(dc_link, &new_connection_type))
@@ -1661,6 +1672,10 @@ static void handle_hpd_rx_irq(void *param)
drm_kms_helper_hotplug_event(dev);
}
}
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   if (hpd_irq_data.bytes.device_service_irq.bits.CP_IRQ)
+   hdcp_handle_cpirq(adev->dm.hdcp_workqueue,  
aconnector->base.index);
+#endif
if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
(dc_link->type == dc_connection_mst_branch))
dm_handle_hpd_rx_irq(aconnector);
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 12/20] drm/amd/display: Update hdcp display config

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to update the hdcp display parameter whenever the link is
updated, so the next time there is an update to hdcp we have the
latest display info

[How]
Create a callback, and use this anytime there is a change in the link. This will
be used later by the dm.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 10 
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 31 
 drivers/gpu/drm/amd/display/dc/dc.h   |  5 ++
 drivers/gpu/drm/amd/display/dc/dc_types.h |  7 +++
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h| 49 +++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  4 +-
 6 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 175275560e75..a3c258840a2d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -825,6 +825,16 @@ struct dc *dc_create(const struct dc_init_data 
*init_params)
 void dc_init_callbacks(struct dc *dc,
const struct dc_callback_init *init_params)
 {
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   dc->ctx->cp_psp = init_params->cp_psp;
+#endif
+}
+
+void dc_deinit_callbacks(struct dc *dc)
+{
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp));
+#endif
 }
 
 void dc_destroy(struct dc **dc)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 1307b533a3f8..0966f8fec414 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2667,6 +2667,24 @@ static enum dc_status deallocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 
return DC_OK;
 }
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
+{
+   struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
+   if (cp_psp && cp_psp->funcs.update_stream_config) {
+   struct cp_psp_stream_config config;
+
+   memset(&config, 0, sizeof(config));
+
+   config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst;
+   config.stream_enc_inst = (uint8_t) 
pipe_ctx->stream_res.stream_enc->id;
+   config.link_enc_inst = pipe_ctx->stream->link->link_enc_hw_inst;
+   config.dpms_off = dpms_off;
+   config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context;
+   cp_psp->funcs.update_stream_config(cp_psp->handle, &config);
+   }
+}
+#endif
 
 void core_link_enable_stream(
struct dc_state *state,
@@ -2727,6 +2745,9 @@ void core_link_enable_stream(
/* Do not touch link on seamless boot optimization. */
if (pipe_ctx->stream->apply_seamless_boot_optimization) {
pipe_ctx->stream->dpms_off = false;
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, false);
+#endif
return;
}
 
@@ -2734,6 +2755,9 @@ void core_link_enable_stream(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
apply_edp_fast_boot_optimization) {
pipe_ctx->stream->dpms_off = false;
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, false);
+#endif
return;
}
 
@@ -2793,6 +2817,9 @@ void core_link_enable_stream(
 
if (dc_is_dp_signal(pipe_ctx->stream->signal))
enable_stream_features(pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, false);
+#endif
}
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
else { // if (IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
@@ -2810,6 +2837,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, true);
+#endif
+
core_dc->hwss.blank_stream(pipe_ctx);
 
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 3b848d4aca8c..ef2130bf3476 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -552,7 +552,11 @@ struct dc_init_data {
 };
 
 struct dc_callback_init {
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct cp_psp cp_psp;
+#else
uint8_t reserved;
+#endif
 };
 
 struct dc *dc_create(const struct dc_init_data *init_params);
@@ -564,6 +568,7 @@ int dc_setup_system_context(struct dc *dc, struct 
dc_phy_addr_space_config *pa_c
 #endif
 void dc_init_ca

[PATCH 19/20] drm/amd/display: only enable HDCP for DCN+

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We don't support HDCP for pre RAVEN asics

[How]
Check if we are RAVEN+. Use this to attach the content_protection
property, this way usermode can't try to enable HDCP on pre DCN asics.

Also we need to update the module on hpd so guard it aswell

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 879b70f2cb0d..a70c1f512dd2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -733,14 +733,16 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
amdgpu_dm_init_color_mod();
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP
-   adev->dm.hdcp_workqueue = hdcp_create_workqueue(&adev->psp, 
&init_params.cp_psp, adev->dm.dc);
+   if (adev->asic_type >= CHIP_RAVEN) {
+   adev->dm.hdcp_workqueue = hdcp_create_workqueue(&adev->psp, 
&init_params.cp_psp, adev->dm.dc);
 
-   if (!adev->dm.hdcp_workqueue)
-   DRM_ERROR("amdgpu: failed to initialize hdcp_workqueue.\n");
-   else
-   DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done %p.\n", 
adev->dm.hdcp_workqueue);
+   if (!adev->dm.hdcp_workqueue)
+   DRM_ERROR("amdgpu: failed to initialize 
hdcp_workqueue.\n");
+   else
+   DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done 
%p.\n", adev->dm.hdcp_workqueue);
 
-   dc_init_callbacks(adev->dm.dc, &init_params);
+   dc_init_callbacks(adev->dm.dc, &init_params);
+   }
 #endif
if (amdgpu_dm_initialize_drm_device(adev)) {
DRM_ERROR(
@@ -1497,7 +1499,8 @@ static void handle_hpd_irq(void *param)
mutex_lock(&aconnector->hpd_lock);
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP
-   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+   if (adev->asic_type >= CHIP_RAVEN)
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
 #endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
@@ -5103,7 +5106,8 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
 #ifdef CONFIG_DRM_AMD_DC_HDCP
-   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+   if (adev->asic_type >= CHIP_RAVEN)
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
 #endif
}
 }
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 07/20] drm/hdcp: update content protection property with uevent

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

drm function is defined and exported to update a connector's
content protection property state and to generate a uevent along
with it.

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  Update only when state is different from old one.
v3:
  KDoc is added [Daniel]
v4:
  KDoc is extended bit more [pekka]
v5:
  Uevent usage is documented at kdoc of "Content Protection" also
  [pekka]

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Acked-by: Pekka Paalanen 
Acked-by: Jani Nikula 
Link: https://patchwork.freedesktop.org/patch/320963/?series=57232&rev=14
---
 drivers/gpu/drm/drm_connector.c | 17 +
 drivers/gpu/drm/drm_hdcp.c  | 34 +
 include/drm/drm_hdcp.h  |  2 ++
 3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 3b0910b36ef5..3a0cacb71235 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -951,10 +951,19 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] 
= {
  * - If the state is DESIRED, kernel should attempt to re-authenticate the
  *   link whenever possible. This includes across disable/enable, dpms,
  *   hotplug, downstream device changes, link status failures, etc..
- * - Userspace is responsible for polling the property to determine when
- *   the value transitions from ENABLED to DESIRED. This signifies the link
- *   is no longer protected and userspace should take appropriate action
- *   (whatever that might be).
+ * - Kernel sends uevent with the connector id and property id through
+ *   @drm_hdcp_update_content_protection, upon below kernel triggered
+ *   scenarios:
+ * DESIRED -> ENABLED  (authentication success)
+ * ENABLED -> DESIRED  (termination of authentication)
+ * - Please note no uevents for userspace triggered property state changes,
+ *   which can't fail such as
+ * DESIRED/ENABLED -> UNDESIRED
+ * UNDESIRED -> DESIRED
+ * - Userspace is responsible for polling the property or listen to uevents
+ *   to determine when the value transitions from ENABLED to DESIRED.
+ *   This signifies the link is no longer protected and userspace should
+ *   take appropriate action (whatever that might be).
  *
  * HDCP Content Type:
  * This Enum property is used by the userspace to declare the content type
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 75402463466b..1e2a50bcab7e 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
  *
  * The content protection will be set to 
&drm_connector_state.content_protection
  *
+ * When kernel triggered content protection state change like DESIRED->ENABLED
+ * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to 
update
+ * the content protection state of a connector.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
@@ -412,3 +416,33 @@ int drm_connector_attach_content_protection_property(
return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
+
+/**
+ * drm_hdcp_update_content_protection - Updates the content protection state
+ * of a connector
+ *
+ * @connector: drm_connector on which content protection state needs an update
+ * @val: New state of the content protection property
+ *
+ * This function can be used by display drivers, to update the kernel triggered
+ * content protection state changes of a drm_connector such as DESIRED->ENABLED
+ * and ENABLED->DESIRED. No uevent for DESIRED->UNDESIRED or 
ENABLED->UNDESIRED,
+ * as userspace is triggering such state change and kernel performs it without
+ * fail.This function update the new state of the property into the connector's
+ * state and generate an uevent to notify the userspace.
+ */
+void drm_hdcp_update_content_protection(struct drm_connector *connector,
+   u64 val)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_connector_state *state = connector->state;
+
+   WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+   if (state->content_protection == val)
+   return;
+
+   state->content_protection = val;
+   drm_sysfs_connector_status_event(connector,
+dev->mode_config.content_protection_property);
+}
+EXPORT_SYMBOL(drm_hdcp_update_content_protection);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 82447af98aa2..06a11202a097 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -292,6 +292,8 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *d

[PATCH 00/20] HDCP 1.4 Content Protection

2019-09-10 Thread Bhawanpreet Lakha
This patch set introduces HDCP 1.4 capability to Asics starting with  Raven(DCN 
1.0).

This only introduces the ability to authenticate and encrypt the link. These
patches by themselves don't constitute a complete and compliant
HDCP content protection solution but are a requirement for such a solution.

NOTE: The 7 patches by Ramalingam have already been merged to drm-misc
but are required to apply the HDCP patches on amd-staging-drm-next

Bhawanpreet Lakha (13):
  drm/amdgpu: psp HDCP init
  drm/amdgpu: psp DTM init
  drm/amd/display: Add HDCP module
  drm/amd/display: add PSP block to verify hdcp steps
  drm/amd/display: Update hdcp display config
  drm/amd/display: Create amdgpu_dm_hdcp
  drm/amd/display: Create dpcd and i2c packing functions
  drm/amd/display: Initialize HDCP work queue
  drm/amd/display: Handle Content protection property changes
  drm/amd/display: handle DP cpirq
  drm/amd/display: Update CP property based on HW query
  drm/amd/display: only enable HDCP for DCN+
  drm/amd/display: Add hdcp to Kconfig

Ramalingam C (7):
  drm: move content protection property to mode_config
  drm: generic fn converting be24 to cpu and vice versa
  drm: revocation check at drm subsystem
  drm/hdcp: gathering hdcp related code into drm_hdcp.c
  drm: Add Content protection type property
  drm: uevent for connector status change
  drm/hdcp: update content protection property with uevent

 Documentation/gpu/drm-kms-helpers.rst |   6 +
 drivers/gpu/drm/Makefile  |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 343 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  32 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   6 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  40 +-
 drivers/gpu/drm/amd/display/Kconfig   |   8 +
 drivers/gpu/drm/amd/display/Makefile  |   7 +
 .../gpu/drm/amd/display/amdgpu_dm/Makefile|   4 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 135 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 342 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|  66 +++
 drivers/gpu/drm/amd/display/dc/Makefile   |   4 +
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  10 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  31 +
 drivers/gpu/drm/amd/display/dc/dc.h   |   5 +
 drivers/gpu/drm/amd/display/dc/dc_types.h |   7 +
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h|  49 ++
 drivers/gpu/drm/amd/display/dc/hdcp/Makefile  |  28 +
 .../gpu/drm/amd/display/dc/hdcp/hdcp_msg.c| 324 +++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   4 +-
 .../gpu/drm/amd/display/include/hdcp_types.h  |  96 
 .../gpu/drm/amd/display/modules/hdcp/Makefile |  32 ++
 .../gpu/drm/amd/display/modules/hdcp/hdcp.c   | 426 ++
 .../gpu/drm/amd/display/modules/hdcp/hdcp.h   | 442 +++
 .../display/modules/hdcp/hdcp1_execution.c| 531 ++
 .../display/modules/hdcp/hdcp1_transition.c   | 307 ++
 .../drm/amd/display/modules/hdcp/hdcp_ddc.c   | 305 ++
 .../drm/amd/display/modules/hdcp/hdcp_log.c   | 163 ++
 .../drm/amd/display/modules/hdcp/hdcp_log.h   | 139 +
 .../drm/amd/display/modules/hdcp/hdcp_psp.c   | 328 +++
 .../drm/amd/display/modules/hdcp/hdcp_psp.h   | 272 +
 .../drm/amd/display/modules/inc/mod_hdcp.h| 289 ++
 drivers/gpu/drm/drm_atomic_uapi.c |   8 +-
 drivers/gpu/drm/drm_connector.c   | 111 ++--
 drivers/gpu/drm/drm_hdcp.c| 448 +++
 drivers/gpu/drm/drm_internal.h|   4 +
 drivers/gpu/drm/drm_sysfs.c   |  37 ++
 drivers/gpu/drm/i915/intel_hdcp.c |   9 +-
 drivers/misc/mei/hdcp/mei_hdcp.c  |   2 +-
 include/drm/drm_connector.h   |  15 +-
 include/drm/drm_hdcp.h|  38 +-
 include/drm/drm_mode_config.h |  12 +
 include/drm/drm_sysfs.h   |   5 +-
 45 files changed, 5407 insertions(+), 68 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/hdcp/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
 create mode 100644 drivers/gpu/drm/amd/display/include/hdcp_types.h
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
 create mode 100644 drivers/gpu/drm/am

[PATCH 11/20] drm/amd/display: add PSP block to verify hdcp steps

2019-09-10 Thread Bhawanpreet Lakha
[Why]
All the HDCP transactions should be verified using PSP.

[How]
This patch calls psp with the correct inputs to verify the steps
of authentication.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../drm/amd/display/modules/hdcp/hdcp_psp.c   | 328 ++
 .../drm/amd/display/modules/hdcp/hdcp_psp.h   | 272 +++
 2 files changed, 600 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
new file mode 100644
index ..646d909bbc37
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#define MAX_NUM_DISPLAYS 24
+
+
+#include "hdcp.h"
+
+#include "amdgpu.h"
+#include "hdcp_psp.h"
+
+enum mod_hdcp_status mod_hdcp_remove_display_topology(struct mod_hdcp *hdcp)
+{
+
+   struct psp_context *psp = hdcp->config.psp.handle;
+   struct ta_dtm_shared_memory *dtm_cmd;
+   struct mod_hdcp_display *display = NULL;
+   uint8_t i;
+
+   dtm_cmd = (struct ta_dtm_shared_memory 
*)psp->dtm_context.dtm_shared_buf;
+
+   for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
+   if (hdcp->connection.displays[i].state == 
MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED) {
+
+   memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
+
+   display = &hdcp->connection.displays[i];
+
+   dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
+   
dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;
+   dtm_cmd->dtm_in_message.topology_update_v2.is_active = 
0;
+   dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
+
+   psp_dtm_invoke(psp, dtm_cmd->cmd_id);
+
+   if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS)
+   return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
+
+   display->state = MOD_HDCP_DISPLAY_ACTIVE;
+   HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
+   }
+   }
+
+   return MOD_HDCP_STATUS_SUCCESS;
+}
+
+enum mod_hdcp_status mod_hdcp_add_display_topology(struct mod_hdcp *hdcp)
+{
+   struct psp_context *psp = hdcp->config.psp.handle;
+   struct ta_dtm_shared_memory *dtm_cmd;
+   struct mod_hdcp_display *display = NULL;
+   struct mod_hdcp_link *link = &hdcp->connection.link;
+   uint8_t i;
+
+   if (!psp->dtm_context.dtm_initialized) {
+   DRM_ERROR("Failed to add display topology, DTM TA is not 
initialized.");
+   return MOD_HDCP_STATUS_FAILURE;
+   }
+
+   dtm_cmd = (struct ta_dtm_shared_memory 
*)psp->dtm_context.dtm_shared_buf;
+
+   for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
+   if (hdcp->connection.displays[i].state == 
MOD_HDCP_DISPLAY_ACTIVE) {
+   display = &hdcp->connection.displays[i];
+
+   memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
+
+   dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
+   
dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;
+   dtm_cmd->dtm_in_message.topology_update_v2.is_active = 
1;
+   dtm_cmd->dtm_in_message.topology_update_v2.controller = 
display->controller;
+   dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = 
link->ddc_line;
+   dtm_cmd->dtm_in_message.topology_update_v2.dig_be = 
link->dig_be;
+   dtm_cmd->dtm_in_message.to

[PATCH 20/20] drm/amd/display: Add hdcp to Kconfig

2019-09-10 Thread Bhawanpreet Lakha
[Why]
HDCP is not fully finished, so we need to be able to
build and run the driver without it.

[How]
Add a Kconfig to toggle it

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/display/Kconfig | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/Kconfig 
b/drivers/gpu/drm/amd/display/Kconfig
index 8154fd637afb..b4504257873a 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -43,6 +43,14 @@ config DRM_AMD_DC_DSC_SUPPORT
Choose this option if you want to have
Dynamic Stream Compression support
 
+config DRM_AMD_DC_HDCP
+bool "Enable HDCP support in DC"
+depends on DRM_AMD_DC
+help
+ Choose this option
+ if you want to support
+ HDCP authentication
+
 config DEBUG_KERNEL_DC
bool "Enable kgdb break in DC"
depends on DRM_AMD_DC
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 14/20] drm/amd/display: Create dpcd and i2c packing functions

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to read and write specific i2c and dpcd messages.

[How]
Created static functions for packing the dpcd and i2c messages for hdcp.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 40 ++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 004b6e8e9ed5..9d11d7695508 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -26,6 +26,41 @@
 #include "amdgpu_dm_hdcp.h"
 #include "amdgpu.h"
 #include "amdgpu_dm.h"
+#include "dm_helpers.h"
+
+bool lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, 
uint32_t size)
+{
+
+   struct dc_link *link = handle;
+   struct i2c_payload i2c_payloads[] = {{true, address, size, (void 
*)data} };
+   struct i2c_command cmd = {i2c_payloads, 1, I2C_COMMAND_ENGINE_HW, 
link->dc->caps.i2c_speed_in_khz};
+
+   return dm_helpers_submit_i2c(link->ctx, link, &cmd);
+}
+
+bool lp_read_i2c(void *handle, uint32_t address, uint8_t offset, uint8_t 
*data, uint32_t size)
+{
+   struct dc_link *link = handle;
+
+   struct i2c_payload i2c_payloads[] = {{true, address, 1, &offset}, 
{false, address, size, data} };
+   struct i2c_command cmd = {i2c_payloads, 2, I2C_COMMAND_ENGINE_HW, 
link->dc->caps.i2c_speed_in_khz};
+
+   return dm_helpers_submit_i2c(link->ctx, link, &cmd);
+}
+
+bool lp_write_dpcd(void *handle, uint32_t address, const uint8_t *data, 
uint32_t size)
+{
+   struct dc_link *link = handle;
+
+   return dm_helpers_dp_write_dpcd(link->ctx, link, address, data, size);
+}
+
+bool lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, uint32_t size)
+{
+   struct dc_link *link = handle;
+
+   return dm_helpers_dp_read_dpcd(link->ctx, link, address, data, size);
+}
 
 static void process_output(struct hdcp_workqueue *hdcp_work)
 {
@@ -220,7 +255,10 @@ struct hdcp_workqueue *hdcp_create_workqueue(void 
*psp_context, struct cp_psp *c
 
hdcp_work[i].hdcp.config.psp.handle =  psp_context;
hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, 
i);
-
+   hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c;
+   hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c;
+   hdcp_work[i].hdcp.config.ddc.funcs.write_dpcd = lp_write_dpcd;
+   hdcp_work[i].hdcp.config.ddc.funcs.read_dpcd = lp_read_dpcd;
}
 
cp_psp->funcs.update_stream_config = update_config;
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 18/20] drm/amd/display: Update CP property based on HW query

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to use HW state to set content protection to ENABLED.
This way we know that the link is encrypted from the HW side

[How]
Create a workqueue that queries the HW every ~2seconds, and sets it to
ENABLED or DESIRED based on the result from the hardware

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 +
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 65 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|  7 +-
 3 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a1895b873ef2..879b70f2cb0d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5387,19 +5387,9 @@ static void update_content_protection(struct 
drm_connector_state *state, const s
 {
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
 
-   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
-   hdcp_add_display(hdcp_w, aconnector->dc_link->link_index);
-
-   /*
-* TODO: ENABLED should be verified using psp, it is planned 
later.
-* Just set this to ENABLED for now
-*/
-   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-
-   return;
-   }
-
-   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED)
+   hdcp_add_display(hdcp_w, aconnector->dc_link->link_index, 
aconnector);
+   else if (state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
hdcp_remove_display(hdcp_w, aconnector->dc_link->link_index, 
aconnector->base.index);
 
 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 9d11d7695508..2443c238c188 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -27,6 +27,7 @@
 #include "amdgpu.h"
 #include "amdgpu_dm.h"
 #include "dm_helpers.h"
+#include 
 
 bool lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, 
uint32_t size)
 {
@@ -82,16 +83,19 @@ static void process_output(struct hdcp_workqueue *hdcp_work)
 
 }
 
-void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index, struct amdgpu_dm_connector *aconnector)
 {
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
 
mutex_lock(&hdcp_w->mutex);
+   hdcp_w->aconnector = aconnector;
 
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
 
+   schedule_delayed_work(&hdcp_w->property_validate_dwork, 
msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
+
process_output(hdcp_w);
 
mutex_unlock(&hdcp_w->mutex);
@@ -106,6 +110,9 @@ void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, 
unsigned int link_ind
 
mod_hdcp_remove_display(&hdcp_w->hdcp, display_index, &hdcp_w->output);
 
+   cancel_delayed_work(&hdcp_w->property_validate_dwork);
+   hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
+
process_output(hdcp_w);
 
mutex_unlock(&hdcp_w->mutex);
@@ -120,6 +127,9 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, 
unsigned int link_inde
 
mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
 
+   cancel_delayed_work(&hdcp_w->property_validate_dwork);
+   hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
+
process_output(hdcp_w);
 
mutex_unlock(&hdcp_w->mutex);
@@ -155,7 +165,58 @@ static void event_callback(struct work_struct *work)
 
 
 }
+static void event_property_update(struct work_struct *work)
+{
+
+   struct hdcp_workqueue *hdcp_work = container_of(work, struct 
hdcp_workqueue, property_update_work);
+   struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector;
+   struct drm_device *dev = hdcp_work->aconnector->base.dev;
+   long ret;
+
+   drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+   mutex_lock(&hdcp_work->mutex);
+
+
+   if (aconnector->base.state->commit) {
+   ret = 
wait_for_completion_interruptible_timeout(&aconnector->base.state->commit->hw_done,
 10 * HZ);
+
+   if (ret == 0) {
+   DRM_ERROR("HDCP state unknown! Setting it to DESIRED");
+   hdcp_work->encryption_status = 
MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
+   }
+   }
+
+   if (hdcp_work->encryption_status =

[PATCH 16/20] drm/amd/display: Handle Content protection property changes

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to manage the content protection property changes for
different usecase, once cp is DESIRED we need to maintain the
ENABLED/DESIRED status for different cases.

[How]
1. Attach the content_protection property

2. HDCP enable (UNDESIRED -> DESIRED)
call into the module with the correct parameters to start
hdcp. Set cp to ENABLED

3. HDCP disable (ENABLED -> UNDESIRED)
Call the module to disable hdcp.

3. Handle Special cases (Hotplug, S3, headless S3, DPMS)
If already ENABLED: set to DESIRED on unplug/suspend/dpms,
and disable hdcp

Then on plugin/resume/dpms: enable HDCP

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2cc95ab0b645..591b8ab9d4ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -68,6 +68,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
@@ -1466,6 +1467,11 @@ amdgpu_dm_update_connector_after_detect(struct 
amdgpu_dm_connector *aconnector)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   /* Set CP to DESIRED if it was ENABLED, so we can re-enable it 
again on hotplug */
+   if (connector->state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   connector->state->content_protection = 
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+#endif
}
 
mutex_unlock(&dev->mode_config.mutex);
@@ -1480,6 +1486,9 @@ static void handle_hpd_irq(void *param)
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct amdgpu_device *adev = dev->dev_private;
+#endif
 
/*
 * In case of failure or MST no need to update connector status or 
notify the OS
@@ -1487,6 +1496,9 @@ static void handle_hpd_irq(void *param)
 */
mutex_lock(&aconnector->hpd_lock);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+#endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
 
@@ -5075,6 +5087,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.freesync_property, 0);
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+#endif
}
 }
 
@@ -5317,6 +5332,63 @@ is_scaling_state_different(const struct 
dm_connector_state *dm_state,
return false;
 }
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+static bool is_content_protection_different(struct drm_connector_state *state,
+   const struct drm_connector_state 
*old_state,
+   const struct drm_connector 
*connector, struct hdcp_workqueue *hdcp_w)
+{
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+
+   /* CP is being re enabled, ignore this */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
+   }
+
+   /* S3 resume case, since old state will always be 0 (UNDESIRED) and the 
restored state will be ENABLED */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /* Check if something is connected/enabled, otherwise we start hdcp but 
nothing is connected/enabled
+* hot-plug, headless s3, dpms
+*/
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && 
connector->dpms == DRM_MODE_DPMS_ON &&
+   aconnector->dc_sink != NULL)
+   return true;
+
+   if (old_state->content_protection == state->content_protection)
+   return false;
+
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   return true;
+
+   return false;
+}
+
+static void update_content_protection(struct drm_connector_state

[PATCH 09/20] drm/amdgpu: psp DTM init

2019-09-10 Thread Bhawanpreet Lakha
DTM is the display topology manager. This is needed to communicate with
psp about the display configurations.

This patch adds
-Loading the firmware
-The functions and definitions for communication with the firmware

v2: Fix formatting

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 154 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  15 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   3 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  11 +-
 4 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index e75d164ea85b..ddb36a834e1c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -941,6 +941,149 @@ static int psp_hdcp_terminate(struct psp_context *psp)
 }
 // HDCP end
 
+// DTM start
+static void psp_prep_dtm_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+uint64_t dtm_ta_mc,
+uint64_t dtm_mc_shared,
+uint32_t dtm_ta_size,
+uint32_t shared_size)
+{
+   cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
+   cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(dtm_ta_mc);
+   cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(dtm_ta_mc);
+   cmd->cmd.cmd_load_ta.app_len = dtm_ta_size;
+
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(dtm_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(dtm_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
+}
+
+static int psp_dtm_init_shared_buf(struct psp_context *psp)
+{
+   int ret;
+
+   /*
+* Allocate 16k memory aligned to 4k from Frame Buffer (local
+* physical) for dtm ta <-> Driver
+*/
+   ret = amdgpu_bo_create_kernel(psp->adev, PSP_DTM_SHARED_MEM_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->dtm_context.dtm_shared_bo,
+ &psp->dtm_context.dtm_shared_mc_addr,
+ &psp->dtm_context.dtm_shared_buf);
+
+   return ret;
+}
+
+static int psp_dtm_load(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   memset(psp->fw_pri_buf, 0, PSP_1_MEG);
+   memcpy(psp->fw_pri_buf, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size);
+
+   psp_prep_dtm_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
+psp->dtm_context.dtm_shared_mc_addr,
+psp->ta_dtm_ucode_size,
+PSP_DTM_SHARED_MEM_SIZE);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   if (!ret) {
+   psp->dtm_context.dtm_initialized = 1;
+   psp->dtm_context.session_id = cmd->resp.session_id;
+   }
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static int psp_dtm_initialize(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->dtm_context.dtm_initialized) {
+   ret = psp_dtm_init_shared_buf(psp);
+   if (ret)
+   return ret;
+   }
+
+   ret = psp_dtm_load(psp);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static void psp_prep_dtm_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+  uint32_t ta_cmd_id,
+  uint32_t dtm_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
+   cmd->cmd.cmd_invoke_cmd.session_id = dtm_session_id;
+   cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
+   /* Note: cmd_invoke_cmd.buf is not used for now */
+}
+
+int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   psp_prep_dtm_ta_invoke_cmd_buf(cmd, ta_cmd_id,
+  psp->dtm_context.session_id);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static int psp_dtm_terminate(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->dtm_context.dtm_initialized)
+   return 0;
+
+   ret = psp_hdcp_unload(psp);
+ 

[PATCH 06/20] drm: uevent for connector status change

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

DRM API for generating uevent for a status changes of connector's
property.

This uevent will have following details related to the status change:

  HOTPLUG=1, CONNECTOR= and PROPERTY=

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  Minor fixes at KDoc comments [Daniel]
v3:
  Check the property is really attached with connector [Daniel]
v4:
  Typos and string length suggestions are addressed [Sean]

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Reviewed-by: Sean Paul 
Acked-by: Pekka Paalanen 
Acked-by: Jani Nikula 
Link: https://patchwork.freedesktop.org/patch/320961/?series=57232&rev=14
---
 drivers/gpu/drm/drm_sysfs.c | 35 +++
 include/drm/drm_sysfs.h |  5 -
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 18b1ac442997..9f0ccec44a04 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include "drm_internal.h"
+#include "drm_crtc_internal.h"
 
 #define to_drm_minor(d) dev_get_drvdata(d)
 #define to_drm_connector(d) dev_get_drvdata(d)
@@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
  * Send a uevent for the DRM device specified by @dev.  Currently we only
  * set HOTPLUG=1 in the uevent environment, but this could be expanded to
  * deal with other types of events.
+ *
+ * Any new uapi should be using the drm_sysfs_connector_status_event()
+ * for uevents on connector status change.
  */
 void drm_sysfs_hotplug_event(struct drm_device *dev)
 {
@@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
+/**
+ * drm_sysfs_connector_status_event - generate a DRM uevent for connector
+ * property status change
+ * @connector: connector on which property status changed
+ * @property: connector property whose status changed.
+ *
+ * Send a uevent for the DRM device specified by @dev.  Currently we
+ * set HOTPLUG=1 and connector id along with the attached property id
+ * related to the status change.
+ */
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+ struct drm_property *property)
+{
+   struct drm_device *dev = connector->dev;
+   char hotplug_str[] = "HOTPLUG=1", conn_id[21], prop_id[21];
+   char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
+
+   WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
+  property->base.id));
+
+   snprintf(conn_id, ARRAY_SIZE(conn_id),
+"CONNECTOR=%u", connector->base.id);
+   snprintf(prop_id, ARRAY_SIZE(prop_id),
+"PROPERTY=%u", property->base.id);
+
+   DRM_DEBUG("generating connector status event\n");
+
+   kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
+}
+EXPORT_SYMBOL(drm_sysfs_connector_status_event);
+
 static void drm_sysfs_release(struct device *dev)
 {
kfree(dev);
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index 4f311e836cdc..d454ef617b2c 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -4,10 +4,13 @@
 
 struct drm_device;
 struct device;
+struct drm_connector;
+struct drm_property;
 
 int drm_class_device_register(struct device *dev);
 void drm_class_device_unregister(struct device *dev);
 
 void drm_sysfs_hotplug_event(struct drm_device *dev);
-
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+ struct drm_property *property);
 #endif
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 08/20] drm/amdgpu: psp HDCP init

2019-09-10 Thread Bhawanpreet Lakha
This patch adds
-Loading the firmware
-The functions and definitions for communication with the firmware

v2: Fix formatting

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 189 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  17 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   3 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  33 +++-
 4 files changed, 240 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index f90a0cd12827..e75d164ea85b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -766,6 +766,181 @@ static int psp_ras_initialize(struct psp_context *psp)
 }
 // ras end
 
+// HDCP start
+static void psp_prep_hdcp_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+ uint64_t hdcp_ta_mc,
+ uint64_t hdcp_mc_shared,
+ uint32_t hdcp_ta_size,
+ uint32_t shared_size)
+{
+   cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
+   cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(hdcp_ta_mc);
+   cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(hdcp_ta_mc);
+   cmd->cmd.cmd_load_ta.app_len = hdcp_ta_size;
+
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo =
+   lower_32_bits(hdcp_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi =
+   upper_32_bits(hdcp_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
+}
+
+static int psp_hdcp_init_shared_buf(struct psp_context *psp)
+{
+   int ret;
+
+   /*
+* Allocate 16k memory aligned to 4k from Frame Buffer (local
+* physical) for hdcp ta <-> Driver
+*/
+   ret = amdgpu_bo_create_kernel(psp->adev, PSP_HDCP_SHARED_MEM_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->hdcp_context.hdcp_shared_bo,
+ &psp->hdcp_context.hdcp_shared_mc_addr,
+ &psp->hdcp_context.hdcp_shared_buf);
+
+   return ret;
+}
+
+static int psp_hdcp_load(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   memset(psp->fw_pri_buf, 0, PSP_1_MEG);
+   memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr,
+  psp->ta_hdcp_ucode_size);
+
+   psp_prep_hdcp_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
+ psp->hdcp_context.hdcp_shared_mc_addr,
+ psp->ta_hdcp_ucode_size,
+ PSP_HDCP_SHARED_MEM_SIZE);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   if (!ret) {
+   psp->hdcp_context.hdcp_initialized = 1;
+   psp->hdcp_context.session_id = cmd->resp.session_id;
+   }
+
+   kfree(cmd);
+
+   return ret;
+}
+static int psp_hdcp_initialize(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->hdcp_context.hdcp_initialized) {
+   ret = psp_hdcp_init_shared_buf(psp);
+   if (ret)
+   return ret;
+   }
+
+   ret = psp_hdcp_load(psp);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+static void psp_prep_hdcp_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+   uint32_t hdcp_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA;
+   cmd->cmd.cmd_unload_ta.session_id = hdcp_session_id;
+}
+
+static int psp_hdcp_unload(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the unloading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   psp_prep_hdcp_ta_unload_cmd_buf(cmd, psp->hdcp_context.session_id);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static void psp_prep_hdcp_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+   uint32_t ta_cmd_id,
+   uint32_t hdcp_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
+   cmd->cmd.cmd_invoke_cmd.session_id = hdcp_session_id;
+   cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
+   /* Note: cmd_invoke_cmd.buf is not used for now */
+}
+
+int psp_hdcp_invoke(st

[PATCH 02/20] drm: generic fn converting be24 to cpu and vice versa

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

Existing functions for converting a 3bytes(be24) of big endian value
into u32 of little endian and vice versa are renamed as

s/drm_hdcp2_seq_num_to_u32/drm_hdcp_be24_to_cpu
s/drm_hdcp2_u32_to_seq_num/drm_hdcp_cpu_to_be24

Signed-off-by: Ramalingam C 
Suggested-by: Daniel Vetter 
cc: Tomas Winkler 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-4-ramalinga...@intel.com
---
 drivers/gpu/drm/i915/intel_hdcp.c | 5 +++--
 drivers/misc/mei/hdcp/mei_hdcp.c  | 2 +-
 include/drm/drm_hdcp.h| 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
b/drivers/gpu/drm/i915/intel_hdcp.c
index 99b007169c49..536cddc74d22 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1306,7 +1306,7 @@ int hdcp2_propagate_stream_management_info(struct 
intel_connector *connector)
 
/* Prepare RepeaterAuth_Stream_Manage msg */
msgs.stream_manage.msg_id = HDCP_2_2_REP_STREAM_MANAGE;
-   drm_hdcp2_u32_to_seq_num(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
+   drm_hdcp_cpu_to_be24(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
 
/* K no of streams is fixed as 1. Stored as big-endian. */
msgs.stream_manage.k = cpu_to_be16(1);
@@ -1371,7 +1371,8 @@ int hdcp2_authenticate_repeater_topology(struct 
intel_connector *connector)
}
 
/* Converting and Storing the seq_num_v to local variable as DWORD */
-   seq_num_v = drm_hdcp2_seq_num_to_u32(msgs.recvid_list.seq_num_v);
+   seq_num_v =
+   drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v);
 
if (seq_num_v < hdcp->seq_num_v) {
/* Roll over of the seq_num_v from repeater. Reauthenticate. */
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index b07000202d4a..417865129407 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -576,7 +576,7 @@ static int mei_hdcp_verify_mprime(struct device *dev,
 
memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
   HDCP_2_2_MPRIME_LEN);
-   drm_hdcp2_u32_to_seq_num(verify_mprime_in.seq_num_m, data->seq_num_m);
+   drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
memcpy(verify_mprime_in.streams, data->streams,
   (data->k * sizeof(struct hdcp2_streamid_type)));
 
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index f243408ecf26..1cc66df05a43 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -252,13 +252,13 @@ struct hdcp2_rep_stream_ready {
  * host format and back
  */
 static inline
-u32 drm_hdcp2_seq_num_to_u32(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN])
+u32 drm_hdcp_be24_to_cpu(const u8 seq_num[HDCP_2_2_SEQ_NUM_LEN])
 {
return (u32)(seq_num[2] | seq_num[1] << 8 | seq_num[0] << 16);
 }
 
 static inline
-void drm_hdcp2_u32_to_seq_num(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
+void drm_hdcp_cpu_to_be24(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
 {
seq_num[0] = val >> 16;
seq_num[1] = val >> 8;
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 03/20] drm: revocation check at drm subsystem

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

On every hdcp revocation check request SRM is read from fw file
/lib/firmware/display_hdcp_srm.bin

SRM table is parsed and stored at drm_hdcp.c, with functions exported
for the services for revocation check from drivers (which
implements the HDCP authentication)

This patch handles the HDCP1.4 and 2.2 versions of SRM table.

v2:
  moved the uAPI to request_firmware_direct() [Daniel]
v3:
  kdoc added. [Daniel]
  srm_header unified and bit field definitions are removed. [Daniel]
  locking improved. [Daniel]
  vrl length violation is fixed. [Daniel]
v4:
  s/__swab16/be16_to_cpu [Daniel]
  be24_to_cpu is done through a global func [Daniel]
  Unused variables are removed. [Daniel]
  unchecked return values are dropped from static funcs [Daniel]

Signed-off-by: Ramalingam C 
Acked-by: Satyeshwar Singh 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-5-ramalinga...@intel.com
---
 Documentation/gpu/drm-kms-helpers.rst |   6 +
 drivers/gpu/drm/Makefile  |   2 +-
 drivers/gpu/drm/drm_hdcp.c| 333 ++
 drivers/gpu/drm/drm_internal.h|   4 +
 drivers/gpu/drm/drm_sysfs.c   |   2 +
 include/drm/drm_hdcp.h|  24 ++
 6 files changed, 370 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_hdcp.c

diff --git a/Documentation/gpu/drm-kms-helpers.rst 
b/Documentation/gpu/drm-kms-helpers.rst
index 14102ae035dc..0fe726a6ee67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -181,6 +181,12 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
:export:
 
+HDCP Helper Functions Reference
+===
+
+.. kernel-doc:: drivers/gpu/drm/drm_hdcp.c
+   :export:
+
 Display Port Helper Functions Reference
 ===
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f204830669e2..7fa09ea00ffd 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,7 @@ drm-y   :=drm_auth.o drm_cache.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-   drm_atomic_uapi.o
+   drm_atomic_uapi.o drm_hdcp.o
 
 drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o 
drm_dma.o drm_scatter.o drm_lock.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
new file mode 100644
index ..5e5409505c31
--- /dev/null
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Intel Corporation.
+ *
+ * Authors:
+ * Ramalingam C 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+struct hdcp_srm {
+   u32 revoked_ksv_cnt;
+   u8 *revoked_ksv_list;
+
+   /* Mutex to protect above struct member */
+   struct mutex mutex;
+} *srm_data;
+
+static inline void drm_hdcp_print_ksv(const u8 *ksv)
+{
+   DRM_DEBUG("\t%#02x, %#02x, %#02x, %#02x, %#02x\n",
+ ksv[0], ksv[1], ksv[2], ksv[3], ksv[4]);
+}
+
+static u32 drm_hdcp_get_revoked_ksv_count(const u8 *buf, u32 vrls_length)
+{
+   u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
+
+   while (parsed_bytes < vrls_length) {
+   vrl_ksv_cnt = *buf;
+   ksv_count += vrl_ksv_cnt;
+
+   vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
+   buf += vrl_sz;
+   parsed_bytes += vrl_sz;
+   }
+
+   /*
+* When vrls are not valid, ksvs are not considered.
+* Hence SRM will be discarded.
+*/
+   if (parsed_bytes != vrls_length)
+   ksv_count = 0;
+
+   return ksv_count;
+}
+
+static u32 drm_hdcp_get_revoked_ksvs(const u8 *buf, u8 *revoked_ksv_list,
+u32 vrls_length)
+{
+   u32 parsed_bytes = 0, ksv_count = 0;
+   u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
+
+   do {
+   vrl_ksv_cnt = *buf;
+   vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
+
+   buf++;
+
+   DRM_DEBUG("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
+ vrl_ksv_cnt);
+   memcpy(revoked_ksv_list, buf, vrl_ksv_sz);
+
+   ksv_count += vrl_ksv_cnt;
+   revoked_ksv_list += vrl_ksv_sz;
+   buf += vrl_ksv_sz;
+
+   parsed_bytes += (vrl_ksv_sz + 1);
+   } while (parsed_bytes < vrls_length);
+
+   return ksv_count;
+}
+
+static inline u32 get_vrl_length(const u8 *buf)
+{
+   return drm_hdcp_be24_to_cpu(buf);
+}
+
+static int drm_hdcp_parse_hdcp1_s

[PATCH 06/20] drm: uevent for connector status change

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

DRM API for generating uevent for a status changes of connector's
property.

This uevent will have following details related to the status change:

  HOTPLUG=1, CONNECTOR= and PROPERTY=

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  Minor fixes at KDoc comments [Daniel]
v3:
  Check the property is really attached with connector [Daniel]
v4:
  Typos and string length suggestions are addressed [Sean]

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Reviewed-by: Sean Paul 
Acked-by: Pekka Paalanen 
Acked-by: Jani Nikula 
Link: https://patchwork.freedesktop.org/patch/320961/?series=57232&rev=14
---
 drivers/gpu/drm/drm_sysfs.c | 35 +++
 include/drm/drm_sysfs.h |  5 -
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 18b1ac442997..9f0ccec44a04 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include "drm_internal.h"
+#include "drm_crtc_internal.h"
 
 #define to_drm_minor(d) dev_get_drvdata(d)
 #define to_drm_connector(d) dev_get_drvdata(d)
@@ -320,6 +321,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
  * Send a uevent for the DRM device specified by @dev.  Currently we only
  * set HOTPLUG=1 in the uevent environment, but this could be expanded to
  * deal with other types of events.
+ *
+ * Any new uapi should be using the drm_sysfs_connector_status_event()
+ * for uevents on connector status change.
  */
 void drm_sysfs_hotplug_event(struct drm_device *dev)
 {
@@ -332,6 +336,37 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
+/**
+ * drm_sysfs_connector_status_event - generate a DRM uevent for connector
+ * property status change
+ * @connector: connector on which property status changed
+ * @property: connector property whose status changed.
+ *
+ * Send a uevent for the DRM device specified by @dev.  Currently we
+ * set HOTPLUG=1 and connector id along with the attached property id
+ * related to the status change.
+ */
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+ struct drm_property *property)
+{
+   struct drm_device *dev = connector->dev;
+   char hotplug_str[] = "HOTPLUG=1", conn_id[21], prop_id[21];
+   char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
+
+   WARN_ON(!drm_mode_obj_find_prop_id(&connector->base,
+  property->base.id));
+
+   snprintf(conn_id, ARRAY_SIZE(conn_id),
+"CONNECTOR=%u", connector->base.id);
+   snprintf(prop_id, ARRAY_SIZE(prop_id),
+"PROPERTY=%u", property->base.id);
+
+   DRM_DEBUG("generating connector status event\n");
+
+   kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
+}
+EXPORT_SYMBOL(drm_sysfs_connector_status_event);
+
 static void drm_sysfs_release(struct device *dev)
 {
kfree(dev);
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index 4f311e836cdc..d454ef617b2c 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -4,10 +4,13 @@
 
 struct drm_device;
 struct device;
+struct drm_connector;
+struct drm_property;
 
 int drm_class_device_register(struct device *dev);
 void drm_class_device_unregister(struct device *dev);
 
 void drm_sysfs_hotplug_event(struct drm_device *dev);
-
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+ struct drm_property *property);
 #endif
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 04/20] drm/hdcp: gathering hdcp related code into drm_hdcp.c

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

Considering the significant size of hdcp related code in drm, all
hdcp related codes are moved into separate file called drm_hdcp.c.

v2:
  Rebased.
v2:
  Rebased.

Signed-off-by: Ramalingam C 
Suggested-by: Daniel Vetter 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-7-ramalinga...@intel.com
---
 drivers/gpu/drm/drm_connector.c | 44 --
 drivers/gpu/drm/drm_hdcp.c  | 47 +
 include/drm/drm_connector.h |  2 --
 include/drm/drm_hdcp.h  |  3 +++
 4 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 0490c204122d..11fcd25bc640 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -823,13 +823,6 @@ static const struct drm_prop_enum_list 
drm_tv_subconnector_enum_list[] = {
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
 drm_tv_subconnector_enum_list)
 
-static struct drm_prop_enum_list drm_cp_enum_list[] = {
-   { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
-   { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
-   { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
-};
-DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
-
 static const struct drm_prop_enum_list hdmi_colorspaces[] = {
/* For Default case, driver will set the colorspace */
{ DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
@@ -1509,43 +1502,6 @@ int drm_connector_attach_scaling_mode_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
 
-/**
- * drm_connector_attach_content_protection_property - attach content protection
- * property
- *
- * @connector: connector to attach CP property on.
- *
- * This is used to add support for content protection on select connectors.
- * Content Protection is intentionally vague to allow for different underlying
- * technologies, however it is most implemented by HDCP.
- *
- * The content protection will be set to 
&drm_connector_state.content_protection
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
-int drm_connector_attach_content_protection_property(
-   struct drm_connector *connector)
-{
-   struct drm_device *dev = connector->dev;
-   struct drm_property *prop =
-   dev->mode_config.content_protection_property;
-
-   if (!prop)
-   prop = drm_property_create_enum(dev, 0, "Content Protection",
-   drm_cp_enum_list,
-   ARRAY_SIZE(drm_cp_enum_list));
-   if (!prop)
-   return -ENOMEM;
-
-   drm_object_attach_property(&connector->base, prop,
-  DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-   dev->mode_config.content_protection_property = prop;
-
-   return 0;
-}
-EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
-
 /**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 5e5409505c31..0da7b3718bad 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -17,6 +17,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 struct hdcp_srm {
u32 revoked_ksv_cnt;
@@ -331,3 +334,47 @@ void drm_teardown_hdcp_srm(struct class *drm_class)
kfree(srm_data);
}
 }
+
+static struct drm_prop_enum_list drm_cp_enum_list[] = {
+   { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+   { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+   { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
+
+/**
+ * drm_connector_attach_content_protection_property - attach content protection
+ * property
+ *
+ * @connector: connector to attach CP property on.
+ *
+ * This is used to add support for content protection on select connectors.
+ * Content Protection is intentionally vague to allow for different underlying
+ * technologies, however it is most implemented by HDCP.
+ *
+ * The content protection will be set to 
&drm_connector_state.content_protection
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_content_protection_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop =
+   dev->mode_config.content_protection_property;
+
+   if (!prop)
+   prop = drm_property_create_enum(dev, 0, "Content Protection",
+   drm_cp_enum_list,
+   ARRAY_SIZE(dr

[PATCH 01/20] drm: move content protection property to mode_config

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

Content protection property is created once and stored in
drm_mode_config. And attached to all HDCP capable connectors.

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-2-ramalinga...@intel.com
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 ++--
 drivers/gpu/drm/drm_connector.c   | 13 +++--
 include/drm/drm_connector.h   |  6 --
 include/drm/drm_mode_config.h |  6 ++
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 428d82662dc4..4131e669785a 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -732,7 +732,7 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->content_type = val;
} else if (property == connector->scaling_mode_property) {
state->scaling_mode = val;
-   } else if (property == connector->content_protection_property) {
+   } else if (property == config->content_protection_property) {
if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
return -EINVAL;
@@ -814,7 +814,7 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->colorspace;
} else if (property == connector->scaling_mode_property) {
*val = state->scaling_mode;
-   } else if (property == connector->content_protection_property) {
+   } else if (property == config->content_protection_property) {
*val = state->content_protection;
} else if (property == config->writeback_fb_id_property) {
/* Writeback framebuffer is one-shot, write and forget */
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b34c3d38bf15..0490c204122d 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1528,18 +1528,19 @@ int drm_connector_attach_content_protection_property(
struct drm_connector *connector)
 {
struct drm_device *dev = connector->dev;
-   struct drm_property *prop;
+   struct drm_property *prop =
+   dev->mode_config.content_protection_property;
 
-   prop = drm_property_create_enum(dev, 0, "Content Protection",
-   drm_cp_enum_list,
-   ARRAY_SIZE(drm_cp_enum_list));
+   if (!prop)
+   prop = drm_property_create_enum(dev, 0, "Content Protection",
+   drm_cp_enum_list,
+   ARRAY_SIZE(drm_cp_enum_list));
if (!prop)
return -ENOMEM;
 
drm_object_attach_property(&connector->base, prop,
   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-
-   connector->content_protection_property = prop;
+   dev->mode_config.content_protection_property = prop;
 
return 0;
 }
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 02a131202add..5e41942e5679 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1061,12 +1061,6 @@ struct drm_connector {
 */
struct drm_property *vrr_capable_property;
 
-   /**
-* @content_protection_property: DRM ENUM property for content
-* protection. See drm_connector_attach_content_protection_property().
-*/
-   struct drm_property *content_protection_property;
-
/**
 * @colorspace_property: Connector property to set the suitable
 * colorspace supported by the sink.
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 7f60e8eb269a..5764ee3c7453 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -836,6 +836,12 @@ struct drm_mode_config {
 */
struct drm_property *writeback_out_fence_ptr_property;
 
+   /**
+* @content_protection_property: DRM ENUM property for content
+* protection. See drm_connector_attach_content_protection_property().
+*/
+   struct drm_property *content_protection_property;
+
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 08/20] drm/amdgpu: psp HDCP init

2019-09-10 Thread Bhawanpreet Lakha
This patch adds
-Loading the firmware
-The functions and definitions for communication with the firmware

v2: Fix formatting

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 189 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  17 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   3 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  33 +++-
 4 files changed, 240 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index f90a0cd12827..e75d164ea85b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -766,6 +766,181 @@ static int psp_ras_initialize(struct psp_context *psp)
 }
 // ras end
 
+// HDCP start
+static void psp_prep_hdcp_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+ uint64_t hdcp_ta_mc,
+ uint64_t hdcp_mc_shared,
+ uint32_t hdcp_ta_size,
+ uint32_t shared_size)
+{
+   cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
+   cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(hdcp_ta_mc);
+   cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(hdcp_ta_mc);
+   cmd->cmd.cmd_load_ta.app_len = hdcp_ta_size;
+
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo =
+   lower_32_bits(hdcp_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi =
+   upper_32_bits(hdcp_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
+}
+
+static int psp_hdcp_init_shared_buf(struct psp_context *psp)
+{
+   int ret;
+
+   /*
+* Allocate 16k memory aligned to 4k from Frame Buffer (local
+* physical) for hdcp ta <-> Driver
+*/
+   ret = amdgpu_bo_create_kernel(psp->adev, PSP_HDCP_SHARED_MEM_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->hdcp_context.hdcp_shared_bo,
+ &psp->hdcp_context.hdcp_shared_mc_addr,
+ &psp->hdcp_context.hdcp_shared_buf);
+
+   return ret;
+}
+
+static int psp_hdcp_load(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   memset(psp->fw_pri_buf, 0, PSP_1_MEG);
+   memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr,
+  psp->ta_hdcp_ucode_size);
+
+   psp_prep_hdcp_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
+ psp->hdcp_context.hdcp_shared_mc_addr,
+ psp->ta_hdcp_ucode_size,
+ PSP_HDCP_SHARED_MEM_SIZE);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   if (!ret) {
+   psp->hdcp_context.hdcp_initialized = 1;
+   psp->hdcp_context.session_id = cmd->resp.session_id;
+   }
+
+   kfree(cmd);
+
+   return ret;
+}
+static int psp_hdcp_initialize(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->hdcp_context.hdcp_initialized) {
+   ret = psp_hdcp_init_shared_buf(psp);
+   if (ret)
+   return ret;
+   }
+
+   ret = psp_hdcp_load(psp);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+static void psp_prep_hdcp_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+   uint32_t hdcp_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA;
+   cmd->cmd.cmd_unload_ta.session_id = hdcp_session_id;
+}
+
+static int psp_hdcp_unload(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the unloading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   psp_prep_hdcp_ta_unload_cmd_buf(cmd, psp->hdcp_context.session_id);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static void psp_prep_hdcp_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+   uint32_t ta_cmd_id,
+   uint32_t hdcp_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
+   cmd->cmd.cmd_invoke_cmd.session_id = hdcp_session_id;
+   cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
+   /* Note: cmd_invoke_cmd.buf is not used for now */
+}
+
+int psp_hdcp_invoke(st

[PATCH 19/20] drm/amd/display: only enable HDCP for DCN+

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We don't support HDCP for pre RAVEN asics

[How]
Check if we are RAVEN+. Use this to attach the content_protection
property, this way usermode can't try to enable HDCP on pre DCN asics.

Also we need to update the module on hpd so guard it aswell

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 879b70f2cb0d..a70c1f512dd2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -733,14 +733,16 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
amdgpu_dm_init_color_mod();
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP
-   adev->dm.hdcp_workqueue = hdcp_create_workqueue(&adev->psp, 
&init_params.cp_psp, adev->dm.dc);
+   if (adev->asic_type >= CHIP_RAVEN) {
+   adev->dm.hdcp_workqueue = hdcp_create_workqueue(&adev->psp, 
&init_params.cp_psp, adev->dm.dc);
 
-   if (!adev->dm.hdcp_workqueue)
-   DRM_ERROR("amdgpu: failed to initialize hdcp_workqueue.\n");
-   else
-   DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done %p.\n", 
adev->dm.hdcp_workqueue);
+   if (!adev->dm.hdcp_workqueue)
+   DRM_ERROR("amdgpu: failed to initialize 
hdcp_workqueue.\n");
+   else
+   DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done 
%p.\n", adev->dm.hdcp_workqueue);
 
-   dc_init_callbacks(adev->dm.dc, &init_params);
+   dc_init_callbacks(adev->dm.dc, &init_params);
+   }
 #endif
if (amdgpu_dm_initialize_drm_device(adev)) {
DRM_ERROR(
@@ -1497,7 +1499,8 @@ static void handle_hpd_irq(void *param)
mutex_lock(&aconnector->hpd_lock);
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP
-   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+   if (adev->asic_type >= CHIP_RAVEN)
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
 #endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
@@ -5103,7 +5106,8 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
 #ifdef CONFIG_DRM_AMD_DC_HDCP
-   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+   if (adev->asic_type >= CHIP_RAVEN)
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
 #endif
}
 }
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 15/20] drm/amd/display: Initialize HDCP work queue

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need this to enable HDCP on linux, as we need events to interact
with the hdcp module

[How]
Add work queue to display manager and handle the creation and destruction
of the queue

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 ++
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c1031121ee8a..2cc95ab0b645 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -37,6 +37,9 @@
 #include "amdgpu_ucode.h"
 #include "atom.h"
 #include "amdgpu_dm.h"
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+#include "amdgpu_dm_hdcp.h"
+#endif
 #include "amdgpu_pm.h"
 
 #include "amd_shared.h"
@@ -644,11 +647,18 @@ void amdgpu_dm_audio_eld_notify(struct amdgpu_device 
*adev, int pin)
 static int amdgpu_dm_init(struct amdgpu_device *adev)
 {
struct dc_init_data init_data;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct dc_callback_init init_params;
+#endif
+
adev->dm.ddev = adev->ddev;
adev->dm.adev = adev;
 
/* Zero all the fields */
memset(&init_data, 0, sizeof(init_data));
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   memset(&init_params, 0, sizeof(init_params));
+#endif
 
mutex_init(&adev->dm.dc_lock);
mutex_init(&adev->dm.audio_lock);
@@ -721,6 +731,16 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 
amdgpu_dm_init_color_mod();
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   adev->dm.hdcp_workqueue = hdcp_create_workqueue(&adev->psp, 
&init_params.cp_psp, adev->dm.dc);
+
+   if (!adev->dm.hdcp_workqueue)
+   DRM_ERROR("amdgpu: failed to initialize hdcp_workqueue.\n");
+   else
+   DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done %p.\n", 
adev->dm.hdcp_workqueue);
+
+   dc_init_callbacks(adev->dm.dc, &init_params);
+#endif
if (amdgpu_dm_initialize_drm_device(adev)) {
DRM_ERROR(
"amdgpu: failed to initialize sw for display support.\n");
@@ -762,6 +782,16 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
 
amdgpu_dm_destroy_drm_device(&adev->dm);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   if (adev->dm.hdcp_workqueue) {
+   hdcp_destroy(adev->dm.hdcp_workqueue);
+   adev->dm.hdcp_workqueue = NULL;
+   }
+
+   if (adev->dm.dc)
+   dc_deinit_callbacks(adev->dm.dc);
+#endif
+
/* DC Destroy TODO: Replace destroy DAL */
if (adev->dm.dc)
dc_destroy(&adev->dm.dc);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index cbd6608f58e6..7a34eca12dab 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -222,6 +222,9 @@ struct amdgpu_display_manager {
struct amdgpu_dm_backlight_caps backlight_caps;
 
struct mod_freesync *freesync_module;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct hdcp_workqueue *hdcp_workqueue;
+#endif
 
struct drm_atomic_state *cached_state;
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 13/20] drm/amd/display: Create amdgpu_dm_hdcp

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to interact with the hdcp module from the DM, the module
has to be interacted with in terms of events

[How]
Create the files needed for linux hdcp. These files manage the events
needed for the dm to interact with the hdcp module.

We use the kernel work queue to process the events needed for
the module

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/Makefile|   4 +
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 241 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|  61 +
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile 
b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index 94911871eb9b..9a3b7bf8ab0b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -31,6 +31,10 @@ ifneq ($(CONFIG_DRM_AMD_DC),)
 AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o
 endif
 
+ifdef CONFIG_DRM_AMD_DC_HDCP
+AMDGPUDM += amdgpu_dm_hdcp.o
+endif
+
 ifneq ($(CONFIG_DEBUG_FS),)
 AMDGPUDM += amdgpu_dm_crc.o amdgpu_dm_debugfs.o
 endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
new file mode 100644
index ..004b6e8e9ed5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "amdgpu_dm_hdcp.h"
+#include "amdgpu.h"
+#include "amdgpu_dm.h"
+
+static void process_output(struct hdcp_workqueue *hdcp_work)
+{
+   struct mod_hdcp_output output = hdcp_work->output;
+
+   if (output.callback_stop)
+   cancel_delayed_work(&hdcp_work->callback_dwork);
+
+   if (output.callback_needed)
+   schedule_delayed_work(&hdcp_work->callback_dwork,
+ msecs_to_jiffies(output.callback_delay));
+
+   if (output.watchdog_timer_stop)
+   cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
+
+   if (output.watchdog_timer_needed)
+   schedule_delayed_work(&hdcp_work->watchdog_timer_dwork,
+ 
msecs_to_jiffies(output.watchdog_timer_delay));
+
+}
+
+void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+   struct mod_hdcp_display *display = &hdcp_work[link_index].display;
+   struct mod_hdcp_link *link = &hdcp_work[link_index].link;
+
+   mutex_lock(&hdcp_w->mutex);
+
+   mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
+
+   process_output(hdcp_w);
+
+   mutex_unlock(&hdcp_w->mutex);
+
+}
+
+void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index,  unsigned int display_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+   mutex_lock(&hdcp_w->mutex);
+
+   mod_hdcp_remove_display(&hdcp_w->hdcp, display_index, &hdcp_w->output);
+
+   process_output(hdcp_w);
+
+   mutex_unlock(&hdcp_w->mutex);
+
+}
+
+void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+   mutex_lock(&hdcp_w->mutex);
+
+   mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
+
+   process_output(hdcp_w);
+
+   mutex_unlock(&hdcp_w->mutex);
+}
+
+void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+{
+   struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+   schedule_work(&hdcp_w->cpirq_work);
+}
+
+
+
+
+static void eve

[PATCH 18/20] drm/amd/display: Update CP property based on HW query

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to use HW state to set content protection to ENABLED.
This way we know that the link is encrypted from the HW side

[How]
Create a workqueue that queries the HW every ~2seconds, and sets it to
ENABLED or DESIRED based on the result from the hardware

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 +
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 65 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|  7 +-
 3 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a1895b873ef2..879b70f2cb0d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5387,19 +5387,9 @@ static void update_content_protection(struct 
drm_connector_state *state, const s
 {
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
 
-   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
-   hdcp_add_display(hdcp_w, aconnector->dc_link->link_index);
-
-   /*
-* TODO: ENABLED should be verified using psp, it is planned 
later.
-* Just set this to ENABLED for now
-*/
-   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-
-   return;
-   }
-
-   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED)
+   hdcp_add_display(hdcp_w, aconnector->dc_link->link_index, 
aconnector);
+   else if (state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
hdcp_remove_display(hdcp_w, aconnector->dc_link->link_index, 
aconnector->base.index);
 
 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 9d11d7695508..2443c238c188 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -27,6 +27,7 @@
 #include "amdgpu.h"
 #include "amdgpu_dm.h"
 #include "dm_helpers.h"
+#include 
 
 bool lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, 
uint32_t size)
 {
@@ -82,16 +83,19 @@ static void process_output(struct hdcp_workqueue *hdcp_work)
 
 }
 
-void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index)
+void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int 
link_index, struct amdgpu_dm_connector *aconnector)
 {
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
 
mutex_lock(&hdcp_w->mutex);
+   hdcp_w->aconnector = aconnector;
 
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
 
+   schedule_delayed_work(&hdcp_w->property_validate_dwork, 
msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
+
process_output(hdcp_w);
 
mutex_unlock(&hdcp_w->mutex);
@@ -106,6 +110,9 @@ void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, 
unsigned int link_ind
 
mod_hdcp_remove_display(&hdcp_w->hdcp, display_index, &hdcp_w->output);
 
+   cancel_delayed_work(&hdcp_w->property_validate_dwork);
+   hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
+
process_output(hdcp_w);
 
mutex_unlock(&hdcp_w->mutex);
@@ -120,6 +127,9 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, 
unsigned int link_inde
 
mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
 
+   cancel_delayed_work(&hdcp_w->property_validate_dwork);
+   hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
+
process_output(hdcp_w);
 
mutex_unlock(&hdcp_w->mutex);
@@ -155,7 +165,58 @@ static void event_callback(struct work_struct *work)
 
 
 }
+static void event_property_update(struct work_struct *work)
+{
+
+   struct hdcp_workqueue *hdcp_work = container_of(work, struct 
hdcp_workqueue, property_update_work);
+   struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector;
+   struct drm_device *dev = hdcp_work->aconnector->base.dev;
+   long ret;
+
+   drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+   mutex_lock(&hdcp_work->mutex);
+
+
+   if (aconnector->base.state->commit) {
+   ret = 
wait_for_completion_interruptible_timeout(&aconnector->base.state->commit->hw_done,
 10 * HZ);
+
+   if (ret == 0) {
+   DRM_ERROR("HDCP state unknown! Setting it to DESIRED");
+   hdcp_work->encryption_status = 
MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
+   }
+   }
+
+   if (hdcp_work->encryption_status =

[PATCH 11/20] drm/amd/display: add PSP block to verify hdcp steps

2019-09-10 Thread Bhawanpreet Lakha
[Why]
All the HDCP transactions should be verified using PSP.

[How]
This patch calls psp with the correct inputs to verify the steps
of authentication.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../drm/amd/display/modules/hdcp/hdcp_psp.c   | 328 ++
 .../drm/amd/display/modules/hdcp/hdcp_psp.h   | 272 +++
 2 files changed, 600 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
new file mode 100644
index ..646d909bbc37
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#define MAX_NUM_DISPLAYS 24
+
+
+#include "hdcp.h"
+
+#include "amdgpu.h"
+#include "hdcp_psp.h"
+
+enum mod_hdcp_status mod_hdcp_remove_display_topology(struct mod_hdcp *hdcp)
+{
+
+   struct psp_context *psp = hdcp->config.psp.handle;
+   struct ta_dtm_shared_memory *dtm_cmd;
+   struct mod_hdcp_display *display = NULL;
+   uint8_t i;
+
+   dtm_cmd = (struct ta_dtm_shared_memory 
*)psp->dtm_context.dtm_shared_buf;
+
+   for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
+   if (hdcp->connection.displays[i].state == 
MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED) {
+
+   memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
+
+   display = &hdcp->connection.displays[i];
+
+   dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
+   
dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;
+   dtm_cmd->dtm_in_message.topology_update_v2.is_active = 
0;
+   dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
+
+   psp_dtm_invoke(psp, dtm_cmd->cmd_id);
+
+   if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS)
+   return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
+
+   display->state = MOD_HDCP_DISPLAY_ACTIVE;
+   HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
+   }
+   }
+
+   return MOD_HDCP_STATUS_SUCCESS;
+}
+
+enum mod_hdcp_status mod_hdcp_add_display_topology(struct mod_hdcp *hdcp)
+{
+   struct psp_context *psp = hdcp->config.psp.handle;
+   struct ta_dtm_shared_memory *dtm_cmd;
+   struct mod_hdcp_display *display = NULL;
+   struct mod_hdcp_link *link = &hdcp->connection.link;
+   uint8_t i;
+
+   if (!psp->dtm_context.dtm_initialized) {
+   DRM_ERROR("Failed to add display topology, DTM TA is not 
initialized.");
+   return MOD_HDCP_STATUS_FAILURE;
+   }
+
+   dtm_cmd = (struct ta_dtm_shared_memory 
*)psp->dtm_context.dtm_shared_buf;
+
+   for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
+   if (hdcp->connection.displays[i].state == 
MOD_HDCP_DISPLAY_ACTIVE) {
+   display = &hdcp->connection.displays[i];
+
+   memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
+
+   dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
+   
dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;
+   dtm_cmd->dtm_in_message.topology_update_v2.is_active = 
1;
+   dtm_cmd->dtm_in_message.topology_update_v2.controller = 
display->controller;
+   dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = 
link->ddc_line;
+   dtm_cmd->dtm_in_message.topology_update_v2.dig_be = 
link->dig_be;
+   dtm_cmd->dtm_in_message.to

[PATCH 16/20] drm/amd/display: Handle Content protection property changes

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to manage the content protection property changes for
different usecase, once cp is DESIRED we need to maintain the
ENABLED/DESIRED status for different cases.

[How]
1. Attach the content_protection property

2. HDCP enable (UNDESIRED -> DESIRED)
call into the module with the correct parameters to start
hdcp. Set cp to ENABLED

3. HDCP disable (ENABLED -> UNDESIRED)
Call the module to disable hdcp.

3. Handle Special cases (Hotplug, S3, headless S3, DPMS)
If already ENABLED: set to DESIRED on unplug/suspend/dpms,
and disable hdcp

Then on plugin/resume/dpms: enable HDCP

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2cc95ab0b645..591b8ab9d4ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -68,6 +68,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
@@ -1466,6 +1467,11 @@ amdgpu_dm_update_connector_after_detect(struct 
amdgpu_dm_connector *aconnector)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   /* Set CP to DESIRED if it was ENABLED, so we can re-enable it 
again on hotplug */
+   if (connector->state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   connector->state->content_protection = 
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+#endif
}
 
mutex_unlock(&dev->mode_config.mutex);
@@ -1480,6 +1486,9 @@ static void handle_hpd_irq(void *param)
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct amdgpu_device *adev = dev->dev_private;
+#endif
 
/*
 * In case of failure or MST no need to update connector status or 
notify the OS
@@ -1487,6 +1496,9 @@ static void handle_hpd_irq(void *param)
 */
mutex_lock(&aconnector->hpd_lock);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+#endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
 
@@ -5075,6 +5087,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.freesync_property, 0);
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+#endif
}
 }
 
@@ -5317,6 +5332,63 @@ is_scaling_state_different(const struct 
dm_connector_state *dm_state,
return false;
 }
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+static bool is_content_protection_different(struct drm_connector_state *state,
+   const struct drm_connector_state 
*old_state,
+   const struct drm_connector 
*connector, struct hdcp_workqueue *hdcp_w)
+{
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+
+   /* CP is being re enabled, ignore this */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
+   }
+
+   /* S3 resume case, since old state will always be 0 (UNDESIRED) and the 
restored state will be ENABLED */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /* Check if something is connected/enabled, otherwise we start hdcp but 
nothing is connected/enabled
+* hot-plug, headless s3, dpms
+*/
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && 
connector->dpms == DRM_MODE_DPMS_ON &&
+   aconnector->dc_sink != NULL)
+   return true;
+
+   if (old_state->content_protection == state->content_protection)
+   return false;
+
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   return true;
+
+   return false;
+}
+
+static void update_content_protection(struct drm_connector_state

[PATCH 07/20] drm/hdcp: update content protection property with uevent

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

drm function is defined and exported to update a connector's
content protection property state and to generate a uevent along
with it.

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  Update only when state is different from old one.
v3:
  KDoc is added [Daniel]
v4:
  KDoc is extended bit more [pekka]
v5:
  Uevent usage is documented at kdoc of "Content Protection" also
  [pekka]

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Acked-by: Pekka Paalanen 
Acked-by: Jani Nikula 
Link: https://patchwork.freedesktop.org/patch/320963/?series=57232&rev=14
---
 drivers/gpu/drm/drm_connector.c | 17 +
 drivers/gpu/drm/drm_hdcp.c  | 34 +
 include/drm/drm_hdcp.h  |  2 ++
 3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 3b0910b36ef5..3a0cacb71235 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -951,10 +951,19 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] 
= {
  * - If the state is DESIRED, kernel should attempt to re-authenticate the
  *   link whenever possible. This includes across disable/enable, dpms,
  *   hotplug, downstream device changes, link status failures, etc..
- * - Userspace is responsible for polling the property to determine when
- *   the value transitions from ENABLED to DESIRED. This signifies the link
- *   is no longer protected and userspace should take appropriate action
- *   (whatever that might be).
+ * - Kernel sends uevent with the connector id and property id through
+ *   @drm_hdcp_update_content_protection, upon below kernel triggered
+ *   scenarios:
+ * DESIRED -> ENABLED  (authentication success)
+ * ENABLED -> DESIRED  (termination of authentication)
+ * - Please note no uevents for userspace triggered property state changes,
+ *   which can't fail such as
+ * DESIRED/ENABLED -> UNDESIRED
+ * UNDESIRED -> DESIRED
+ * - Userspace is responsible for polling the property or listen to uevents
+ *   to determine when the value transitions from ENABLED to DESIRED.
+ *   This signifies the link is no longer protected and userspace should
+ *   take appropriate action (whatever that might be).
  *
  * HDCP Content Type:
  * This Enum property is used by the userspace to declare the content type
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 75402463466b..1e2a50bcab7e 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -372,6 +372,10 @@ DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
  *
  * The content protection will be set to 
&drm_connector_state.content_protection
  *
+ * When kernel triggered content protection state change like DESIRED->ENABLED
+ * and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to 
update
+ * the content protection state of a connector.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
@@ -412,3 +416,33 @@ int drm_connector_attach_content_protection_property(
return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
+
+/**
+ * drm_hdcp_update_content_protection - Updates the content protection state
+ * of a connector
+ *
+ * @connector: drm_connector on which content protection state needs an update
+ * @val: New state of the content protection property
+ *
+ * This function can be used by display drivers, to update the kernel triggered
+ * content protection state changes of a drm_connector such as DESIRED->ENABLED
+ * and ENABLED->DESIRED. No uevent for DESIRED->UNDESIRED or 
ENABLED->UNDESIRED,
+ * as userspace is triggering such state change and kernel performs it without
+ * fail.This function update the new state of the property into the connector's
+ * state and generate an uevent to notify the userspace.
+ */
+void drm_hdcp_update_content_protection(struct drm_connector *connector,
+   u64 val)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_connector_state *state = connector->state;
+
+   WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+   if (state->content_protection == val)
+   return;
+
+   state->content_protection = val;
+   drm_sysfs_connector_status_event(connector,
+dev->mode_config.content_protection_property);
+}
+EXPORT_SYMBOL(drm_hdcp_update_content_protection);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 82447af98aa2..06a11202a097 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -292,6 +292,8 @@ bool drm_hdcp_check_ksvs_revoked(struct drm_device *d

[PATCH 00/20] HDCP 1.4 Content Protection

2019-09-10 Thread Bhawanpreet Lakha
This patch set introduces HDCP 1.4 capability to Asics starting with  Raven(DCN 
1.0).

This only introduces the ability to authenticate and encrypt the link. These
patches by themselves don't constitute a complete and compliant
HDCP content protection solution but are a requirement for such a solution.

NOTE: The 7 patches by Ramalingam have already been merged to drm-misc
but are required to apply the HDCP patches on amd-staging-drm-next

Bhawanpreet Lakha (13):
  drm/amdgpu: psp HDCP init
  drm/amdgpu: psp DTM init
  drm/amd/display: Add HDCP module
  drm/amd/display: add PSP block to verify hdcp steps
  drm/amd/display: Update hdcp display config
  drm/amd/display: Create amdgpu_dm_hdcp
  drm/amd/display: Create dpcd and i2c packing functions
  drm/amd/display: Initialize HDCP work queue
  drm/amd/display: Handle Content protection property changes
  drm/amd/display: handle DP cpirq
  drm/amd/display: Update CP property based on HW query
  drm/amd/display: only enable HDCP for DCN+
  drm/amd/display: Add hdcp to Kconfig

Ramalingam C (7):
  drm: move content protection property to mode_config
  drm: generic fn converting be24 to cpu and vice versa
  drm: revocation check at drm subsystem
  drm/hdcp: gathering hdcp related code into drm_hdcp.c
  drm: Add Content protection type property
  drm: uevent for connector status change
  drm/hdcp: update content protection property with uevent

 Documentation/gpu/drm-kms-helpers.rst |   6 +
 drivers/gpu/drm/Makefile  |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 343 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  32 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   6 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  40 +-
 drivers/gpu/drm/amd/display/Kconfig   |   8 +
 drivers/gpu/drm/amd/display/Makefile  |   7 +
 .../gpu/drm/amd/display/amdgpu_dm/Makefile|   4 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 135 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 342 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|  66 +++
 drivers/gpu/drm/amd/display/dc/Makefile   |   4 +
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  10 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  31 +
 drivers/gpu/drm/amd/display/dc/dc.h   |   5 +
 drivers/gpu/drm/amd/display/dc/dc_types.h |   7 +
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h|  49 ++
 drivers/gpu/drm/amd/display/dc/hdcp/Makefile  |  28 +
 .../gpu/drm/amd/display/dc/hdcp/hdcp_msg.c| 324 +++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   4 +-
 .../gpu/drm/amd/display/include/hdcp_types.h  |  96 
 .../gpu/drm/amd/display/modules/hdcp/Makefile |  32 ++
 .../gpu/drm/amd/display/modules/hdcp/hdcp.c   | 426 ++
 .../gpu/drm/amd/display/modules/hdcp/hdcp.h   | 442 +++
 .../display/modules/hdcp/hdcp1_execution.c| 531 ++
 .../display/modules/hdcp/hdcp1_transition.c   | 307 ++
 .../drm/amd/display/modules/hdcp/hdcp_ddc.c   | 305 ++
 .../drm/amd/display/modules/hdcp/hdcp_log.c   | 163 ++
 .../drm/amd/display/modules/hdcp/hdcp_log.h   | 139 +
 .../drm/amd/display/modules/hdcp/hdcp_psp.c   | 328 +++
 .../drm/amd/display/modules/hdcp/hdcp_psp.h   | 272 +
 .../drm/amd/display/modules/inc/mod_hdcp.h| 289 ++
 drivers/gpu/drm/drm_atomic_uapi.c |   8 +-
 drivers/gpu/drm/drm_connector.c   | 111 ++--
 drivers/gpu/drm/drm_hdcp.c| 448 +++
 drivers/gpu/drm/drm_internal.h|   4 +
 drivers/gpu/drm/drm_sysfs.c   |  37 ++
 drivers/gpu/drm/i915/intel_hdcp.c |   9 +-
 drivers/misc/mei/hdcp/mei_hdcp.c  |   2 +-
 include/drm/drm_connector.h   |  15 +-
 include/drm/drm_hdcp.h|  38 +-
 include/drm/drm_mode_config.h |  12 +
 include/drm/drm_sysfs.h   |   5 +-
 45 files changed, 5407 insertions(+), 68 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/hdcp/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
 create mode 100644 drivers/gpu/drm/amd/display/include/hdcp_types.h
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
 create mode 100644 drivers/gpu/drm/am

[PATCH 12/20] drm/amd/display: Update hdcp display config

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to update the hdcp display parameter whenever the link is
updated, so the next time there is an update to hdcp we have the
latest display info

[How]
Create a callback, and use this anytime there is a change in the link. This will
be used later by the dm.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 10 
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 31 
 drivers/gpu/drm/amd/display/dc/dc.h   |  5 ++
 drivers/gpu/drm/amd/display/dc/dc_types.h |  7 +++
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h| 49 +++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  4 +-
 6 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 175275560e75..a3c258840a2d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -825,6 +825,16 @@ struct dc *dc_create(const struct dc_init_data 
*init_params)
 void dc_init_callbacks(struct dc *dc,
const struct dc_callback_init *init_params)
 {
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   dc->ctx->cp_psp = init_params->cp_psp;
+#endif
+}
+
+void dc_deinit_callbacks(struct dc *dc)
+{
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp));
+#endif
 }
 
 void dc_destroy(struct dc **dc)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 1307b533a3f8..0966f8fec414 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2667,6 +2667,24 @@ static enum dc_status deallocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 
return DC_OK;
 }
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
+{
+   struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
+   if (cp_psp && cp_psp->funcs.update_stream_config) {
+   struct cp_psp_stream_config config;
+
+   memset(&config, 0, sizeof(config));
+
+   config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst;
+   config.stream_enc_inst = (uint8_t) 
pipe_ctx->stream_res.stream_enc->id;
+   config.link_enc_inst = pipe_ctx->stream->link->link_enc_hw_inst;
+   config.dpms_off = dpms_off;
+   config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context;
+   cp_psp->funcs.update_stream_config(cp_psp->handle, &config);
+   }
+}
+#endif
 
 void core_link_enable_stream(
struct dc_state *state,
@@ -2727,6 +2745,9 @@ void core_link_enable_stream(
/* Do not touch link on seamless boot optimization. */
if (pipe_ctx->stream->apply_seamless_boot_optimization) {
pipe_ctx->stream->dpms_off = false;
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, false);
+#endif
return;
}
 
@@ -2734,6 +2755,9 @@ void core_link_enable_stream(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
apply_edp_fast_boot_optimization) {
pipe_ctx->stream->dpms_off = false;
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, false);
+#endif
return;
}
 
@@ -2793,6 +2817,9 @@ void core_link_enable_stream(
 
if (dc_is_dp_signal(pipe_ctx->stream->signal))
enable_stream_features(pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, false);
+#endif
}
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
else { // if (IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
@@ -2810,6 +2837,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+   update_psp_stream_config(pipe_ctx, true);
+#endif
+
core_dc->hwss.blank_stream(pipe_ctx);
 
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 3b848d4aca8c..ef2130bf3476 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -552,7 +552,11 @@ struct dc_init_data {
 };
 
 struct dc_callback_init {
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct cp_psp cp_psp;
+#else
uint8_t reserved;
+#endif
 };
 
 struct dc *dc_create(const struct dc_init_data *init_params);
@@ -564,6 +568,7 @@ int dc_setup_system_context(struct dc *dc, struct 
dc_phy_addr_space_config *pa_c
 #endif
 void dc_init_ca

[PATCH 17/20] drm/amd/display: handle DP cpirq

2019-09-10 Thread Bhawanpreet Lakha
[Why]
This is needed for DP as DP can send us info using irq.

[How]
Check if irq bit is set on short pulse and call the
function that handles cpirq in amdgpu_dm_hdcp

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 591b8ab9d4ad..a1895b873ef2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1617,6 +1617,12 @@ static void handle_hpd_rx_irq(void *param)
struct dc_link *dc_link = aconnector->dc_link;
bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   union hpd_irq_data hpd_irq_data;
+   struct amdgpu_device *adev = dev->dev_private;
+
+   memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
+#endif
 
/*
 * TODO:Temporary add mutex to protect hpd interrupt not have a gpio
@@ -1626,7 +1632,12 @@ static void handle_hpd_rx_irq(void *param)
if (dc_link->type != dc_connection_mst_branch)
mutex_lock(&aconnector->hpd_lock);
 
+
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   if (dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL) &&
+#else
if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
+#endif
!is_mst_root_connector) {
/* Downstream Port status changed. */
if (!dc_link_detect_sink(dc_link, &new_connection_type))
@@ -1661,6 +1672,10 @@ static void handle_hpd_rx_irq(void *param)
drm_kms_helper_hotplug_event(dev);
}
}
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   if (hpd_irq_data.bytes.device_service_irq.bits.CP_IRQ)
+   hdcp_handle_cpirq(adev->dm.hdcp_workqueue,  
aconnector->base.index);
+#endif
if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
(dc_link->type == dc_connection_mst_branch))
dm_handle_hpd_rx_irq(aconnector);
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 20/20] drm/amd/display: Add hdcp to Kconfig

2019-09-10 Thread Bhawanpreet Lakha
[Why]
HDCP is not fully finished, so we need to be able to
build and run the driver without it.

[How]
Add a Kconfig to toggle it

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/display/Kconfig | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/Kconfig 
b/drivers/gpu/drm/amd/display/Kconfig
index 8154fd637afb..b4504257873a 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -43,6 +43,14 @@ config DRM_AMD_DC_DSC_SUPPORT
Choose this option if you want to have
Dynamic Stream Compression support
 
+config DRM_AMD_DC_HDCP
+bool "Enable HDCP support in DC"
+depends on DRM_AMD_DC
+help
+ Choose this option
+ if you want to support
+ HDCP authentication
+
 config DEBUG_KERNEL_DC
bool "Enable kgdb break in DC"
depends on DRM_AMD_DC
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 14/20] drm/amd/display: Create dpcd and i2c packing functions

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to read and write specific i2c and dpcd messages.

[How]
Created static functions for packing the dpcd and i2c messages for hdcp.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 40 ++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 004b6e8e9ed5..9d11d7695508 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -26,6 +26,41 @@
 #include "amdgpu_dm_hdcp.h"
 #include "amdgpu.h"
 #include "amdgpu_dm.h"
+#include "dm_helpers.h"
+
+bool lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, 
uint32_t size)
+{
+
+   struct dc_link *link = handle;
+   struct i2c_payload i2c_payloads[] = {{true, address, size, (void 
*)data} };
+   struct i2c_command cmd = {i2c_payloads, 1, I2C_COMMAND_ENGINE_HW, 
link->dc->caps.i2c_speed_in_khz};
+
+   return dm_helpers_submit_i2c(link->ctx, link, &cmd);
+}
+
+bool lp_read_i2c(void *handle, uint32_t address, uint8_t offset, uint8_t 
*data, uint32_t size)
+{
+   struct dc_link *link = handle;
+
+   struct i2c_payload i2c_payloads[] = {{true, address, 1, &offset}, 
{false, address, size, data} };
+   struct i2c_command cmd = {i2c_payloads, 2, I2C_COMMAND_ENGINE_HW, 
link->dc->caps.i2c_speed_in_khz};
+
+   return dm_helpers_submit_i2c(link->ctx, link, &cmd);
+}
+
+bool lp_write_dpcd(void *handle, uint32_t address, const uint8_t *data, 
uint32_t size)
+{
+   struct dc_link *link = handle;
+
+   return dm_helpers_dp_write_dpcd(link->ctx, link, address, data, size);
+}
+
+bool lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, uint32_t size)
+{
+   struct dc_link *link = handle;
+
+   return dm_helpers_dp_read_dpcd(link->ctx, link, address, data, size);
+}
 
 static void process_output(struct hdcp_workqueue *hdcp_work)
 {
@@ -220,7 +255,10 @@ struct hdcp_workqueue *hdcp_create_workqueue(void 
*psp_context, struct cp_psp *c
 
hdcp_work[i].hdcp.config.psp.handle =  psp_context;
hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, 
i);
-
+   hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c;
+   hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c;
+   hdcp_work[i].hdcp.config.ddc.funcs.write_dpcd = lp_write_dpcd;
+   hdcp_work[i].hdcp.config.ddc.funcs.read_dpcd = lp_read_dpcd;
}
 
cp_psp->funcs.update_stream_config = update_config;
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 09/20] drm/amdgpu: psp DTM init

2019-09-10 Thread Bhawanpreet Lakha
DTM is the display topology manager. This is needed to communicate with
psp about the display configurations.

This patch adds
-Loading the firmware
-The functions and definitions for communication with the firmware

v2: Fix formatting

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   | 154 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h   |  15 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |   3 +
 drivers/gpu/drm/amd/amdgpu/psp_v10_0.c|  11 +-
 4 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index e75d164ea85b..ddb36a834e1c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -941,6 +941,149 @@ static int psp_hdcp_terminate(struct psp_context *psp)
 }
 // HDCP end
 
+// DTM start
+static void psp_prep_dtm_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+uint64_t dtm_ta_mc,
+uint64_t dtm_mc_shared,
+uint32_t dtm_ta_size,
+uint32_t shared_size)
+{
+   cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
+   cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(dtm_ta_mc);
+   cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(dtm_ta_mc);
+   cmd->cmd.cmd_load_ta.app_len = dtm_ta_size;
+
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(dtm_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(dtm_mc_shared);
+   cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
+}
+
+static int psp_dtm_init_shared_buf(struct psp_context *psp)
+{
+   int ret;
+
+   /*
+* Allocate 16k memory aligned to 4k from Frame Buffer (local
+* physical) for dtm ta <-> Driver
+*/
+   ret = amdgpu_bo_create_kernel(psp->adev, PSP_DTM_SHARED_MEM_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->dtm_context.dtm_shared_bo,
+ &psp->dtm_context.dtm_shared_mc_addr,
+ &psp->dtm_context.dtm_shared_buf);
+
+   return ret;
+}
+
+static int psp_dtm_load(struct psp_context *psp)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   memset(psp->fw_pri_buf, 0, PSP_1_MEG);
+   memcpy(psp->fw_pri_buf, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size);
+
+   psp_prep_dtm_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
+psp->dtm_context.dtm_shared_mc_addr,
+psp->ta_dtm_ucode_size,
+PSP_DTM_SHARED_MEM_SIZE);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   if (!ret) {
+   psp->dtm_context.dtm_initialized = 1;
+   psp->dtm_context.session_id = cmd->resp.session_id;
+   }
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static int psp_dtm_initialize(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->dtm_context.dtm_initialized) {
+   ret = psp_dtm_init_shared_buf(psp);
+   if (ret)
+   return ret;
+   }
+
+   ret = psp_dtm_load(psp);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static void psp_prep_dtm_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
+  uint32_t ta_cmd_id,
+  uint32_t dtm_session_id)
+{
+   cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
+   cmd->cmd.cmd_invoke_cmd.session_id = dtm_session_id;
+   cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
+   /* Note: cmd_invoke_cmd.buf is not used for now */
+}
+
+int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
+{
+   int ret;
+   struct psp_gfx_cmd_resp *cmd;
+
+   /*
+* TODO: bypass the loading in sriov for now
+*/
+   if (amdgpu_sriov_vf(psp->adev))
+   return 0;
+
+   cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+   if (!cmd)
+   return -ENOMEM;
+
+   psp_prep_dtm_ta_invoke_cmd_buf(cmd, ta_cmd_id,
+  psp->dtm_context.session_id);
+
+   ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
+
+   kfree(cmd);
+
+   return ret;
+}
+
+static int psp_dtm_terminate(struct psp_context *psp)
+{
+   int ret;
+
+   if (!psp->dtm_context.dtm_initialized)
+   return 0;
+
+   ret = psp_hdcp_unload(psp);
+ 

[PATCH 05/20] drm: Add Content protection type property

2019-09-10 Thread Bhawanpreet Lakha
From: Ramalingam C 

This patch adds a DRM ENUM property to the selected connectors.
This property is used for mentioning the protected content's type
from userspace to kernel HDCP authentication.

Type of the stream is decided by the protected content providers.
Type 0 content can be rendered on any HDCP protected display wires.
But Type 1 content can be rendered only on HDCP2.2 protected paths.

So when a userspace sets this property to Type 1 and starts the HDCP
enable, kernel will honour it only if HDCP2.2 authentication is through
for type 1. Else HDCP enable will be failed.

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  cp_content_type is replaced with content_protection_type [daniel]
  check at atomic_set_property is removed [Maarten]
v3:
  %s/content_protection_type/hdcp_content_type [Pekka]
v4:
  property is created for the first requested connector and then reused.
[Danvet]
v5:
  kernel doc nits addressed [Daniel]
  Rebased as part of patch reordering.
v6:
  Kernel docs are modified [pekka]
v7:
  More details in Kernel docs. [pekka]
v8:
  Few more clarification into kernel doc of content type [pekka]
v9:
  Small fixes in coding style.
v10:
  Moving DRM_MODE_HDCP_CONTENT_TYPEx definition to drm_hdcp.h [pekka]

Signed-off-by: Ramalingam C 
Reviewed-by: Daniel Vetter 
Acked-by: Pekka Paalanen 
Acked-by: Jani Nikula 
Link: https://patchwork.freedesktop.org/patch/320957/?series=57232&rev=14
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 +++
 drivers/gpu/drm/drm_connector.c   | 51 +++
 drivers/gpu/drm/drm_hdcp.c| 36 +-
 drivers/gpu/drm/i915/intel_hdcp.c |  4 ++-
 include/drm/drm_connector.h   |  7 +
 include/drm/drm_hdcp.h|  7 -
 include/drm/drm_mode_config.h |  6 
 7 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 4131e669785a..a85f3ccfe699 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -738,6 +738,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
return -EINVAL;
}
state->content_protection = val;
+   } else if (property == config->hdcp_content_type_property) {
+   state->hdcp_content_type = val;
} else if (property == connector->colorspace_property) {
state->colorspace = val;
} else if (property == config->writeback_fb_id_property) {
@@ -816,6 +818,8 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->scaling_mode;
} else if (property == config->content_protection_property) {
*val = state->content_protection;
+   } else if (property == config->hdcp_content_type_property) {
+   *val = state->hdcp_content_type;
} else if (property == config->writeback_fb_id_property) {
/* Writeback framebuffer is one-shot, write and forget */
*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 11fcd25bc640..3b0910b36ef5 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -956,6 +956,57 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] 
= {
  *   is no longer protected and userspace should take appropriate action
  *   (whatever that might be).
  *
+ * HDCP Content Type:
+ * This Enum property is used by the userspace to declare the content type
+ * of the display stream, to kernel. Here display stream stands for any
+ * display content that userspace intended to display through HDCP
+ * encryption.
+ *
+ * Content Type of a stream is decided by the owner of the stream, as
+ * "HDCP Type0" or "HDCP Type1".
+ *
+ * The value of the property can be one of the below:
+ *   - "HDCP Type0": DRM_MODE_HDCP_CONTENT_TYPE0 = 0
+ *   - "HDCP Type1": DRM_MODE_HDCP_CONTENT_TYPE1 = 1
+ *
+ * When kernel starts the HDCP authentication (see "Content Protection"
+ * for details), it uses the content type in "HDCP Content Type"
+ * for performing the HDCP authentication with the display sink.
+ *
+ * Please note in HDCP spec versions, a link can be authenticated with
+ * HDCP 2.2 for Content Type 0/Content Type 1. Where as a link can be
+ * authenticated with HDCP1.4 only for Content Type 0(though it is implicit
+ * in nature. As there is no reference for Content Type in HDCP1.4).
+ *
+ * HDCP2.2 authentication protocol itself takes the "Content Type" as a
+ * parameter, which is a input for the DP HDCP2.2 encryption algo.
+ *
+ * In case of Type 0 content protection request, kernel driver can choose
+ * either of HDCP spec ver

[PATCH] drm/amdgpu: Fix mutex lock from atomic context.

2019-09-10 Thread Andrey Grodzovsky
Problem:
amdgpu_ras_reserve_bad_pages was moved to amdgpu_ras_reset_gpu
because writing to EEPROM during ASIC reset was unstable.
But for ERREVENT_ATHUB_INTERRUPT amdgpu_ras_reset_gpu is called
directly from ISR context and so locking is not allowed. Also it's
irrelevant for this partilcular interrupt as this is generic RAS
interrupt and not memory errors specific.

Fix:
Avoid calling amdgpu_ras_reserve_bad_pages if not in task context.

Signed-off-by: Andrey Grodzovsky 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 012034d..dd5da3c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -504,7 +504,9 @@ static inline int amdgpu_ras_reset_gpu(struct amdgpu_device 
*adev,
/* save bad page to eeprom before gpu reset,
 * i2c may be unstable in gpu reset
 */
-   amdgpu_ras_reserve_bad_pages(adev);
+   if (in_task())
+   amdgpu_ras_reserve_bad_pages(adev);
+
if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
schedule_work(&ras->recovery_work);
return 0;
-- 
2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] Fix Xorg abort on exit in RHEL 7.7+

2019-09-10 Thread Grigorev, Slava
RHEL adds an extra LeaveVT calls to xf86CrtcCloseScreen when they build X server
for the purpose to drop drm master.

Signed-off-by: Slava Grigorev 
---
 src/amdgpu_kms.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 3280972..9efc482 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -2285,7 +2285,9 @@ void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn)
struct drmmode_fb *black_fb =

amdgpu_pixmap_get_fb(black_scanout.pixmap);
 
-   amdgpu_pixmap_clear(black_scanout.pixmap);
+   if (!dixPrivateKeyRegistered(rrPrivKey))
+   
amdgpu_pixmap_clear(black_scanout.pixmap);
+
amdgpu_glamor_finish(pScrn);
 
for (i = 0; i < xf86_config->num_crtc; i++) {
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] Revert "drm/amdgpu/nbio7.4: add hw bug workaround for vega20"

2019-09-10 Thread Russell, Kent
This reverts commit e01f2d41895102d824c6b8f5e011dd5e286d5e8b.

VG20 did not require this workaround, as the fix is in the VBIOS.
Leave VG10/12 workaround as some older shipped cards do not have the
VBIOS fix in place, and the kernel workaround is required in those
situations

Change-Id: I2d7c394ce9d205d97be6acfa5edc4635951fdadf
Signed-off-by: Kent Russell 
---
 drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c 
b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
index 2d171bf07ad5..dafd9b7d31d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
@@ -308,13 +308,7 @@ static void nbio_v7_4_detect_hw_virt(struct amdgpu_device 
*adev)
 
 static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
 {
-   uint32_t def, data;
-
-   def = data = RREG32_PCIE(smnPCIE_CI_CNTL);
-   data = REG_SET_FIELD(data, PCIE_CI_CNTL, CI_SLV_ORDERING_DIS, 1);
 
-   if (def != data)
-   WREG32_PCIE(smnPCIE_CI_CNTL, data);
 }
 
 static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct 
amdgpu_device *adev)
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [Nouveau] [Intel-gfx] [PATCH v6 08/17] drm/ttm: use gem vma_node

2019-09-10 Thread Thierry Reding
On Sat, Sep 07, 2019 at 09:58:46PM -0400, Ilia Mirkin wrote:
> On Wed, Aug 21, 2019 at 7:55 AM Thierry Reding  
> wrote:
> >
> > On Wed, Aug 21, 2019 at 04:33:58PM +1000, Ben Skeggs wrote:
> > > On Wed, 14 Aug 2019 at 20:14, Gerd Hoffmann  wrote:
> > > >
> > > >   Hi,
> > > >
> > > > > > Changing the order doesn't look hard.  Patch attached (untested, 
> > > > > > have no
> > > > > > test hardware).  But maybe I missed some detail ...
> > > > >
> > > > > I came up with something very similar by splitting up nouveau_bo_new()
> > > > > into allocation and initialization steps, so that when necessary the 
> > > > > GEM
> > > > > object can be initialized in between. I think that's slightly more
> > > > > flexible and easier to understand than a boolean flag.
> > > >
> > > > Yes, that should work too.
> > > >
> > > > Acked-by: Gerd Hoffmann 
> > > Acked-by: Ben Skeggs 
> >
> > Thanks guys, applied to drm-misc-next.
> 
> Hi Thierry,
> 
> Initial investigations suggest that this commit currently in drm-next
> 
> commit 019cbd4a4feb3aa3a917d78e7110e3011bbff6d5
> Author: Thierry Reding 
> Date:   Wed Aug 14 11:00:48 2019 +0200
> 
> drm/nouveau: Initialize GEM object before TTM object
> 
> breaks nouveau userspace which tries to allocate GEM objects with a
> non-page-aligned size. Previously nouveau_gem_new would just call
> nouveau_bo_init which would call nouveau_bo_fixup_align before
> initializing the GEM object. With this change, it is done after. What
> do you think -- OK to just move that bit of logic into the new
> nouveau_bo_alloc() (and make size/align be pointers so that they can
> be fixed up?)

Hi Ilia,

sorry, got side-tracked earlier and forgot to send this out. I'll turn
this into a proper patch, but if you manage to find the time to test
this while I work out the userspace issues that are preventing me from
testing this more thoroughly, that'd be great.

Thierry

--- >8 ---
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index e918b437af17..7d5ede756711 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -186,8 +186,8 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
 }
 
 struct nouveau_bo *
-nouveau_bo_alloc(struct nouveau_cli *cli, u64 size, u32 flags, u32 tile_mode,
-u32 tile_flags)
+nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 flags,
+u32 tile_mode, u32 tile_flags)
 {
struct nouveau_drm *drm = cli->drm;
struct nouveau_bo *nvbo;
@@ -195,8 +195,8 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 size, u32 
flags, u32 tile_mode,
struct nvif_vmm *vmm = cli->svm.cli ? &cli->svm.vmm : &cli->vmm.vmm;
int i, pi = -1;
 
-   if (!size) {
-   NV_WARN(drm, "skipped size %016llx\n", size);
+   if (!*size) {
+   NV_WARN(drm, "skipped size %016llx\n", *size);
return ERR_PTR(-EINVAL);
}
 
@@ -266,7 +266,7 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 size, u32 
flags, u32 tile_mode,
pi = i;
 
/* Stop once the buffer is larger than the current page size. */
-   if (size >= 1ULL << vmm->page[i].shift)
+   if (*size >= 1ULL << vmm->page[i].shift)
break;
}
 
@@ -281,6 +281,8 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 size, u32 
flags, u32 tile_mode,
}
nvbo->page = vmm->page[pi].shift;
 
+   nouveau_bo_fixup_align(nvbo, flags, align, size);
+
return nvbo;
 }
 
@@ -292,12 +294,11 @@ nouveau_bo_init(struct nouveau_bo *nvbo, u64 size, int 
align, u32 flags,
size_t acc_size;
int ret;
 
-   acc_size = ttm_bo_dma_acc_size(nvbo->bo.bdev, size, sizeof(*nvbo));
-
-   nouveau_bo_fixup_align(nvbo, flags, &align, &size);
nvbo->bo.mem.num_pages = size >> PAGE_SHIFT;
nouveau_bo_placement_set(nvbo, flags, 0);
 
+   acc_size = ttm_bo_dma_acc_size(nvbo->bo.bdev, size, sizeof(*nvbo));
+
ret = ttm_bo_init(nvbo->bo.bdev, &nvbo->bo, size, type,
  &nvbo->placement, align >> PAGE_SHIFT, false,
  acc_size, sg, robj, nouveau_bo_del_ttm);
@@ -318,7 +319,8 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align,
struct nouveau_bo *nvbo;
int ret;
 
-   nvbo = nouveau_bo_alloc(cli, size, flags, tile_mode, tile_flags);
+   nvbo = nouveau_bo_alloc(cli, &size, &align, flags, tile_mode,
+   tile_flags);
if (IS_ERR(nvbo))
return PTR_ERR(nvbo);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h 
b/drivers/gpu/drm/nouveau/nouveau_bo.h
index 62930d834fba..38f9d8350963 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -71,8 +71,8 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo 
**pnvbo)
 extern struct ttm_bo_driver nouveau_bo_driver;
 
 void n

Re: [Patch] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10

2019-09-10 Thread Yin, Tianci (Rico)
Thanks Tao!

From: Zhou1, Tao 
Sent: Tuesday, September 10, 2019 18:24
To: Yin, Tianci (Rico) ; amd-gfx@lists.freedesktop.org 

Cc: Zhang, Hawking ; Xu, Feifei ; 
Long, Gang 
Subject: RE: [Patch] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10


Reviewed-by: Tao Zhou mailto:tao.zh...@amd.com>>



From: Yin, Tianci (Rico) 
Sent: 2019年9月10日 16:59
To: amd-gfx@lists.freedesktop.org
Cc: Zhang, Hawking ; Zhou1, Tao ; Xu, 
Feifei ; Long, Gang 
Subject: [Patch] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA10




___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

RE: [PATCH] drm/amdgpu/sriov: add ring_stop before ring_create in psp v11 code

2019-09-10 Thread Zhang, Jack (Jian)
ping

-Original Message-
From: amd-gfx  On Behalf Of Jack Zhang
Sent: Tuesday, September 10, 2019 4:09 PM
To: amd-gfx@lists.freedesktop.org
Cc: Zhang, Jack (Jian) 
Subject: [PATCH] drm/amdgpu/sriov: add ring_stop before ring_create in psp v11 
code

psp  v11 code missed ring stop in ring create function(VMR) while psp v3.1 code 
had the code. This will cause VM destroy1 fail and psp ring create fail.

For SIOV-VF, ring_stop should not be deleted in ring_create function.

Signed-off-by: Jack Zhang 
---
 drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 61 +++---
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
index cddfa3c..8e9b34a 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
@@ -397,6 +397,34 @@ static bool psp_v11_0_support_vmr_ring(struct psp_context 
*psp)
return false;
 }
 
+static int psp_v11_0_ring_stop(struct psp_context *psp,
+ enum psp_ring_type ring_type)
+{
+   int ret = 0;
+   struct amdgpu_device *adev = psp->adev;
+
+   /* Write the ring destroy command*/
+   if (psp_v11_0_support_vmr_ring(psp))
+   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
+GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
+   else
+   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
+GFX_CTRL_CMD_ID_DESTROY_RINGS);
+
+   /* there might be handshake issue with hardware which needs delay */
+   mdelay(20);
+
+   /* Wait for response flag (bit 31) */
+   if (psp_v11_0_support_vmr_ring(psp))
+   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_101),
+  0x8000, 0x8000, false);
+   else
+   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_64),
+  0x8000, 0x8000, false);
+
+   return ret;
+}
+
 static int psp_v11_0_ring_create(struct psp_context *psp,
enum psp_ring_type ring_type)
 {
@@ -406,6 +434,12 @@ static int psp_v11_0_ring_create(struct psp_context *psp,
struct amdgpu_device *adev = psp->adev;
 
if (psp_v11_0_support_vmr_ring(psp)) {
+   ret = psp_v11_0_ring_stop(psp, ring_type);
+   if (ret) {
+   DRM_ERROR("psp_v11_0_ring_stop_sriov failed!\n");
+   return ret;
+   }
+
/* Write low address of the ring to C2PMSG_102 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg); @@ 
-450,33 +484,6 @@ static int psp_v11_0_ring_create(struct psp_context *psp,
return ret;
 }
 
-static int psp_v11_0_ring_stop(struct psp_context *psp,
- enum psp_ring_type ring_type)
-{
-   int ret = 0;
-   struct amdgpu_device *adev = psp->adev;
-
-   /* Write the ring destroy command*/
-   if (psp_v11_0_support_vmr_ring(psp))
-   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
-GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
-   else
-   WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
-GFX_CTRL_CMD_ID_DESTROY_RINGS);
-
-   /* there might be handshake issue with hardware which needs delay */
-   mdelay(20);
-
-   /* Wait for response flag (bit 31) */
-   if (psp_v11_0_support_vmr_ring(psp))
-   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_101),
-  0x8000, 0x8000, false);
-   else
-   ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, 
mmMP0_SMN_C2PMSG_64),
-  0x8000, 0x8000, false);
-
-   return ret;
-}
 
 static int psp_v11_0_ring_destroy(struct psp_context *psp,
 enum psp_ring_type ring_type)
--
2.7.4

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  1   2   >