RE: [PATCH 6/6] drm/amdgpu: check if we need to reset at init time (v2)

2019-01-08 Thread Quan, Evan
Series is Reviewed-by: Evan Quan 

> -Original Message-
> From: amd-gfx  On Behalf Of Alex
> Deucher
> Sent: 2019年1月9日 6:12
> To: amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander 
> Subject: [PATCH 6/6] drm/amdgpu: check if we need to reset at init time (v2)
> 
> To deal with situations like kexec or GPU VM passthrough where the device
> may have been used previously without a proper GPU reset between.
> 
> v2: rebase
> 
> bug: https://bugs.freedesktop.org/show_bug.cgi?id=108585
> bug: https://bugs.freedesktop.org/show_bug.cgi?id=108754
> Signed-off-by: Alex Deucher 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 1a558dc41ba6..8a61764e64cf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -2550,6 +2550,17 @@ int amdgpu_device_init(struct amdgpu_device
> *adev,
>   /* detect if we are with an SRIOV vbios */
>   amdgpu_device_detect_sriov_bios(adev);
> 
> + /* check if we need to reset the asic
> +  *  E.g., driver was not cleanly unloaded previously, etc.
> +  */
> + if (amdgpu_asic_need_reset_on_init(adev)) {
> + r = amdgpu_asic_reset(adev);
> + if (r) {
> + dev_err(adev->dev, "asic reset on init failed\n");
> + goto failed;
> + }
> + }
> +
>   /* Post card if necessary */
>   if (amdgpu_device_need_post(adev)) {
>   if (!adev->bios) {
> --
> 2.20.1
> 
> ___
> 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] drm/amdgpu: expose sclk and mclk via hwmon

2019-01-08 Thread Quan, Evan
Reviewed-by: Evan Quan 

> -Original Message-
> From: amd-gfx  On Behalf Of Alex
> Deucher
> Sent: 2018年12月11日 5:17
> To: amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander 
> Subject: [PATCH] drm/amdgpu: expose sclk and mclk via hwmon
> 
> Expose sclk (gfx clock) and mclk (memory clock) via
> hwmon compatible interface.  hwmon does not actually
> formally specify a frequency type attribute, but these
> are compatible with the format of the other attributes
> exposed via hwmon.  Units are hertz.
> 
> freq1_input - GPU gfx/compute clock in hertz
> freq2_input - GPU memory clock in hertz (dGPU only)
> 
> Signed-off-by: Alex Deucher 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 93
> ++
>  1 file changed, 93 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 1f61ed95727c..6d52428fc45b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -1516,6 +1516,75 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   return count;
>  }
> 
> +static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
> +   struct device_attribute *attr,
> +   char *buf)
> +{
> + struct amdgpu_device *adev = dev_get_drvdata(dev);
> + struct drm_device *ddev = adev->ddev;
> + uint32_t sclk;
> + int r, size = sizeof(sclk);
> +
> + /* Can't get voltage when the card is off */
> + if  ((adev->flags & AMD_IS_PX) &&
> +  (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> + return -EINVAL;
> +
> + /* sanity check PP is enabled */
> + if (!(adev->powerplay.pp_funcs &&
> +   adev->powerplay.pp_funcs->read_sensor))
> +   return -EINVAL;
> +
> + /* get the sclk */
> + r = amdgpu_dpm_read_sensor(adev,
> AMDGPU_PP_SENSOR_GFX_SCLK,
> +(void *), );
> + if (r)
> + return r;
> +
> + return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000);
> +}
> +
> +static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "sclk\n");
> +}
> +
> +static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
> +   struct device_attribute *attr,
> +   char *buf)
> +{
> + struct amdgpu_device *adev = dev_get_drvdata(dev);
> + struct drm_device *ddev = adev->ddev;
> + uint32_t mclk;
> + int r, size = sizeof(mclk);
> +
> + /* Can't get voltage when the card is off */
> + if  ((adev->flags & AMD_IS_PX) &&
> +  (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> + return -EINVAL;
> +
> + /* sanity check PP is enabled */
> + if (!(adev->powerplay.pp_funcs &&
> +   adev->powerplay.pp_funcs->read_sensor))
> +   return -EINVAL;
> +
> + /* get the sclk */
> + r = amdgpu_dpm_read_sensor(adev,
> AMDGPU_PP_SENSOR_GFX_MCLK,
> +(void *), );
> + if (r)
> + return r;
> +
> + return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000);
> +}
> +
> +static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "mclk\n");
> +}
> 
>  /**
>   * DOC: hwmon
> @@ -1532,6 +1601,10 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   *
>   * - GPU fan
>   *
> + * - GPU gfx/compute engine clock
> + *
> + * - GPU memory clock (dGPU only)
> + *
>   * hwmon interfaces for GPU temperature:
>   *
>   * - temp1_input: the on die GPU temperature in millidegrees Celsius
> @@ -1576,6 +1649,12 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   *
>   * - fan[1-*]_enable: Enable or disable the sensors.1: Enable 0: Disable
>   *
> + * hwmon interfaces for GPU clocks:
> + *
> + * - freq1_input: the gfx/compute clock in hertz
> + *
> + * - freq2_input: the memory clock in hertz
> + *
>   * You can use hwmon tools like sensors to view this information on your
> system.
>   *
>   */
> @@ -1600,6 +1679,10 @@ static SENSOR_DEVICE_ATTR(power1_average,
> S_IRUGO, amdgpu_hwmon_show_power_avg,
>  static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO,
> amdgpu_hwmon_show_power_cap_max, NULL, 0);
>  static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO,
> amdgpu_hwmon_show_power_cap_min, NULL, 0);
>  static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR,
> amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0);
> +static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO,
> amdgpu_hwmon_show_sclk, NULL, 0);
> +static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO,
> 

Re: [PATCH 1/1] drm/amdkfd: Don't assign dGPUs to APU topology devices

2019-01-08 Thread Alex Deucher
On Tue, Jan 8, 2019 at 6:29 PM Kuehling, Felix  wrote:
>
> dGPUs need their own topology devices. Don't assign them to APU topology
> devices with CPU cores.
>
> Bug: https://github.com/RadeonOpenCompute/ROCK-Kernel-Driver/issues/66
> Signed-off-by: Felix Kuehling 

Acked-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c 
> b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> index 4734f1a..09da916 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> @@ -1093,8 +1093,6 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu)
>   * the GPU device is not already present in the topology device
>   * list then return NULL. This means a new topology device has to
>   * be created for this GPU.
> - * TODO: Rather than assiging @gpu to first topology device withtout
> - * gpu attached, it will better to have more stringent check.
>   */
>  static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
>  {
> @@ -1102,12 +1100,20 @@ static struct kfd_topology_device 
> *kfd_assign_gpu(struct kfd_dev *gpu)
> struct kfd_topology_device *out_dev = NULL;
>
> down_write(_lock);
> -   list_for_each_entry(dev, _device_list, list)
> +   list_for_each_entry(dev, _device_list, list) {
> +   /* Discrete GPUs need their own topology device list
> +* entries. Don't assign them to CPU/APU nodes.
> +*/
> +   if (!gpu->device_info->needs_iommu_device &&
> +   dev->node_props.cpu_cores_count)
> +   continue;
> +
> if (!dev->gpu && (dev->node_props.simd_count > 0)) {
> dev->gpu = gpu;
> out_dev = dev;
> break;
> }
> +   }
> up_write(_lock);
> return out_dev;
>  }
> --
> 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


Re: [PATCH] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA20

2019-01-08 Thread Zhang, Jerry(Junwei)

On 1/9/19 10:23 AM, Zhou1, Tao wrote:



-Original Message-
From: amd-gfx  On Behalf Of
Zhang, Jerry(Junwei)
Sent: 2019年1月9日 9:39
To: Zhou1, Tao ; amd-gfx@lists.freedesktop.org
Cc: Li, Yukun1 
Subject: Re: [PATCH] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA20

On 1/8/19 6:55 PM, Tao Zhou wrote:

Fix CPDMA hang in PRT mode for both of VEGA10 and VEGA20

Change-Id: I0e5e089d2192063c4a04fa6dbd534f25eb0177be
Signed-off-by: Tao Zhou 
Tested-by: Yukun.Li 
---
   drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 +-
   1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 968b127c6c8f..fbca0494f871 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -113,7 +113,10 @@ static const struct soc15_reg_golden

golden_settings_gc_9_0[] =

SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI,

0x, 0x4a2c0e68),

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, 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)
IIRC, the CP_DEBUG is the key to fix the CPDMA hang, do we need other
settings?
or just to align the settings with latest status?

Jerry


Set CPF_INT_DMA in reg CP_MECx_F32_INT_DIS for Compute and set
DISABLE_GFX_HALT_ON_UTCL1_ERROR in CP_DEBUG for GFX.

All the settings are needed.


Thanks for confirmation. Almost forgot compute. That's fine.
BTW, not sure PRT is used for compute as well.

Jerry



Tao


   };

   static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
@@ -135,10 +138,7 @@ static const struct soc15_reg_golden

golden_settings_gc_9_0_vg10[] =

SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2,

0x0003, 0x0002),

SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1,

0x000f, 0x01000107),

SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x1800,

0x0800),

-   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, mmWD_UTCL1_CNTL,

0x0800,

+0x0880)
   };

   static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] =

___
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] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA20

2019-01-08 Thread Zhou1, Tao


> -Original Message-
> From: amd-gfx  On Behalf Of
> Zhang, Jerry(Junwei)
> Sent: 2019年1月9日 9:39
> To: Zhou1, Tao ; amd-gfx@lists.freedesktop.org
> Cc: Li, Yukun1 
> Subject: Re: [PATCH] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA20
> 
> On 1/8/19 6:55 PM, Tao Zhou wrote:
> > Fix CPDMA hang in PRT mode for both of VEGA10 and VEGA20
> >
> > Change-Id: I0e5e089d2192063c4a04fa6dbd534f25eb0177be
> > Signed-off-by: Tao Zhou 
> > Tested-by: Yukun.Li 
> > ---
> >   drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 +-
> >   1 file changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> > b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> > index 968b127c6c8f..fbca0494f871 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> > @@ -113,7 +113,10 @@ static const struct soc15_reg_golden
> golden_settings_gc_9_0[] =
> > SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI,
> 0x, 0x4a2c0e68),
> > 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, 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)
> IIRC, the CP_DEBUG is the key to fix the CPDMA hang, do we need other
> settings?
> or just to align the settings with latest status?
> 
> Jerry
> 
Set CPF_INT_DMA in reg CP_MECx_F32_INT_DIS for Compute and set 
DISABLE_GFX_HALT_ON_UTCL1_ERROR in CP_DEBUG for GFX.

All the settings are needed.

Tao

> >   };
> >
> >   static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
> > @@ -135,10 +138,7 @@ static const struct soc15_reg_golden
> golden_settings_gc_9_0_vg10[] =
> > SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2,
> 0x0003, 0x0002),
> > SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1,
> 0x000f, 0x01000107),
> > SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x1800,
> 0x0800),
> > -   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, mmWD_UTCL1_CNTL,
> 0x0800,
> > +0x0880)
> >   };
> >
> >   static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] =
> 
> ___
> 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] drm/amdgpu: fix CPDMA hang in PRT mode for VEGA20

2019-01-08 Thread Zhang, Jerry(Junwei)

On 1/8/19 6:55 PM, Tao Zhou wrote:

Fix CPDMA hang in PRT mode for both of VEGA10 and VEGA20

Change-Id: I0e5e089d2192063c4a04fa6dbd534f25eb0177be
Signed-off-by: Tao Zhou 
Tested-by: Yukun.Li 
---
  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 968b127c6c8f..fbca0494f871 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -113,7 +113,10 @@ static const struct soc15_reg_golden 
golden_settings_gc_9_0[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0x, 
0x4a2c0e68),
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, 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)
IIRC, the CP_DEBUG is the key to fix the CPDMA hang, do we need other 
settings?

or just to align the settings with latest status?

Jerry


  };
  
  static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =

@@ -135,10 +138,7 @@ static const struct soc15_reg_golden 
golden_settings_gc_9_0_vg10[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2, 0x0003, 
0x0002),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x000f, 
0x01000107),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x1800, 0x0800),
-   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, mmWD_UTCL1_CNTL, 0x0800, 0x0880)
  };
  
  static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] =


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


Re: [PATCH 0/6] kexec fixes

2019-01-08 Thread Deucher, Alexander
Yes, the checks are taken from the existing SMU and PSP code.


Alex


From: Kuehling, Felix
Sent: Tuesday, January 8, 2019 6:22:48 PM
To: Alex Deucher; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander
Subject: Re: [PATCH 0/6] kexec fixes

Thanks for this. I trust that your method for detecting that SMU or PSP
are running is correct. With that caveat the series is Reviewed-by:
Felix Kuehling 

Regards,
  Felix

On 2019-01-08 5:11 p.m., Alex Deucher wrote:
> Fixes for kexec.  The GPU needs to be reset before the driver
> can be loaded again reliably.  Needed for kexec for booting some
> ppc platforms.  See:
> https://bugs.freedesktop.org/show_bug.cgi?id=108585
>
> Alex Deucher (6):
>   drm/amdgpu: add need_reset_on_init asic callback (v2)
>   drm/amdgpu/si: add need_reset_on_init asic callback for SI (v2)
>   drm/amdgpu/cik: add need_reset_on_init asic callback for CIK (v2)
>   drm/amdgpu/vi: add need_reset_on_init asic callback for VI (v2)
>   drm/amdgpu/soc15: add need_reset_on_init asic callback for SOC15 (v2)
>   drm/amdgpu: check if we need to reset at init time (v2)
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  3 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++
>  drivers/gpu/drm/amd/amdgpu/cik.c   | 18 ++
>  drivers/gpu/drm/amd/amdgpu/si.c|  6 ++
>  drivers/gpu/drm/amd/amdgpu/soc15.c | 20 
>  drivers/gpu/drm/amd/amdgpu/vi.c| 18 ++
>  6 files changed, 76 insertions(+)
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH v5 18/20] drm/dp_mst: Start tracking per-port VCPI allocations

2019-01-08 Thread Lyude Paul
There has been a TODO waiting for quite a long time in
drm_dp_mst_topology.c:

/* We cannot rely on port->vcpi.num_slots to update
 * topology_state->avail_slots as the port may not exist if the parent
 * branch device was unplugged. This should be fixed by tracking
 * per-port slot allocation in drm_dp_mst_topology_state instead of
 * depending on the caller to tell us how many slots to release.
 */

That's not the only reason we should fix this: forcing the driver to
track the VCPI allocations throughout a state's atomic check is
error prone, because it means that extra care has to be taken with the
order that drm_dp_atomic_find_vcpi_slots() and
drm_dp_atomic_release_vcpi_slots() are called in in order to ensure
idempotency. Currently the only driver actually using these helpers,
i915, doesn't even do this correctly: multiple ->best_encoder() checks
with i915's current implementation would not be idempotent and would
over-allocate VCPI slots, something I learned trying to implement
fallback retraining in MST.

So: simplify this whole mess, and teach drm_dp_atomic_find_vcpi_slots()
and drm_dp_atomic_release_vcpi_slots() to track the VCPI allocations for
each port. This allows us to ensure idempotency without having to rely
on the driver as much. Additionally: the driver doesn't need to do any
kind of VCPI slot tracking anymore if it doesn't need it for it's own
internal state.

Additionally; this adds a new drm_dp_mst_atomic_check() helper which
must be used by atomic drivers to perform validity checks for the new
VCPI allocations incurred by a state.

Also: update the documentation and make it more obvious that these
/must/ be called by /all/ atomic drivers supporting MST.

Changes since v9:
* Add some missing changes that were requested by danvet that I forgot
  about after I redid all of the kref stuff:
  * Remove unnecessary state changes in intel_dp_mst_atomic_check
  * Cleanup atomic check logic for VCPI allocations - all we need to check in
compute_config is whether or not this state disables a CRTC, then free
VCPI based off that

Changes since v8:
 * Fix compile errors, whoops!

Changes since v7:
 - Don't check for mixed stale/valid VCPI allocations, just rely on
 connector registration to stop such erroneous modesets

Changes since v6:
 - Keep a kref to all of the ports we have allocations on. This required
   a good bit of changing to when we call drm_dp_find_vcpi_slots(),
   mainly that we need to ensure that we only redo VCPI allocations on
   actual mode or CRTC changes, not crtc_state->active changes.
   Additionally, we no longer take the registration of the DRM connector
   for each port into account because so long as we have a kref to the
   port in the new or previous atomic state, the connector will stay
   registered.
 - Use the small changes to drm_dp_put_port() to add even more error
   checking to make misusage of the helpers more obvious. I added this
   after having to chase down various use-after-free conditions that
   started popping up from the new helpers so no one else has to
   troubleshoot that.
 - Move some accidental DRM_DEBUG_KMS() calls to DRM_DEBUG_ATOMIC()
 - Update documentation again, note that find/release() should both not be
   called on the same port in a single atomic check phase (but multiple
   calls to one or the other is OK)

Changes since v4:
 - Don't skip the atomic checks for VCPI allocations if no new VCPI
   allocations happen in a state. This makes the next change I'm about
   to list here a lot easier to implement.
 - Don't ignore VCPI allocations on destroyed ports, instead ensure that
   when ports are destroyed and still have VCPI allocations in the
   topology state, the only state changes allowed are releasing said
   ports' VCPI. This prevents a state with a mix of VCPI allocations
   from destroyed ports, and allocations from valid ports.

Changes since v3:
 - Don't release VCPI allocations in the topology state immediately in
   drm_dp_atomic_release_vcpi_slots(), instead mark them as 0 and skip
   over them in drm_dp_mst_duplicate_state(). This makes it so
   drm_dp_atomic_release_vcpi_slots() is still idempotent while also
   throwing warnings if the driver messes up it's book keeping and tries
   to release VCPI slots on a port that doesn't have any pre-existing
   VCPI allocation - danvet
 - Change mst_state/state in some debugging messages to "mst state"

Changes since v2:
 - Use kmemdup() for duplicating MST state - danvet
 - Move port validation out of duplicate state callback - danvet
 - Handle looping through MST topology states in
   drm_dp_mst_atomic_check() so the driver doesn't have to do it
 - Fix documentation in drm_dp_atomic_find_vcpi_slots()
 - Move the atomic check for each individual topology state into it's
   own function, reduces indenting
 - Don't consider "stale" MST ports when calculating the bandwidth
   requirements. This is needed because originally we 

[PATCH v5 20/20] drm/nouveau: Use atomic VCPI helpers for MST

2019-01-08 Thread Lyude Paul
Currently, nouveau uses the yolo method of setting up MST displays: it
uses the old VCPI helpers (drm_dp_find_vcpi_slots()) for computing the
display configuration. These helpers don't take care to make sure they
take a reference to the mstb port that they're checking, and
additionally don't actually check whether or not the topology still has
enough bandwidth to provide the VCPI tokens required.

So, drop usage of the old helpers and move entirely over to the atomic
helpers.

Changes since v6:
* Cleanup atomic check logic and remove a bunch of unneeded checks -
  danvet
Changes since v5:
* Update nv50_msto_atomic_check() and nv50_mstc_atomic_check() to the
  new requirements for drm_dp_atomic_find_vcpi_slots() and
  drm_dp_atomic_release_vcpi_slots()

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 54 ++---
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 67f7bf97e5d9..53d6c8df8f68 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -762,16 +762,23 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_state,
   struct drm_connector_state *conn_state)
 {
-   struct nv50_mstc *mstc = nv50_mstc(conn_state->connector);
+   struct drm_atomic_state *state = crtc_state->state;
+   struct drm_connector *connector = conn_state->connector;
+   struct nv50_mstc *mstc = nv50_mstc(connector);
struct nv50_mstm *mstm = mstc->mstm;
-   int bpp = conn_state->connector->display_info.bpc * 3;
+   int bpp = connector->display_info.bpc * 3;
int slots;
 
-   mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, bpp);
+   mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
+bpp);
 
-   slots = drm_dp_find_vcpi_slots(>mgr, mstc->pbn);
-   if (slots < 0)
-   return slots;
+   if (drm_atomic_crtc_needs_modeset(crtc_state) &&
+   !drm_connector_is_unregistered(connector)) {
+   slots = drm_dp_atomic_find_vcpi_slots(state, >mgr,
+ mstc->port, mstc->pbn);
+   if (slots < 0)
+   return slots;
+   }
 
return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
   mstc->native);
@@ -934,12 +941,43 @@ nv50_mstc_get_modes(struct drm_connector *connector)
return ret;
 }
 
+static int
+nv50_mstc_atomic_check(struct drm_connector *connector,
+  struct drm_connector_state *new_conn_state)
+{
+   struct drm_atomic_state *state = new_conn_state->state;
+   struct nv50_mstc *mstc = nv50_mstc(connector);
+   struct drm_dp_mst_topology_mgr *mgr = >mstm->mgr;
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, connector);
+   struct drm_crtc_state *crtc_state;
+   struct drm_crtc *new_crtc = new_conn_state->crtc;
+
+   if (!old_conn_state->crtc)
+   return 0;
+
+   /* We only want to free VCPI if this state disables the CRTC on this
+* connector
+*/
+   if (new_crtc) {
+   crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
+
+   if (!crtc_state ||
+   !drm_atomic_crtc_needs_modeset(crtc_state) ||
+   crtc_state->enable)
+   return 0;
+   }
+
+   return drm_dp_atomic_release_vcpi_slots(state, mgr, mstc->port);
+}
+
 static const struct drm_connector_helper_funcs
 nv50_mstc_help = {
.get_modes = nv50_mstc_get_modes,
.mode_valid = nv50_mstc_mode_valid,
.best_encoder = nv50_mstc_best_encoder,
.atomic_best_encoder = nv50_mstc_atomic_best_encoder,
+   .atomic_check = nv50_mstc_atomic_check,
 };
 
 static enum drm_connector_status
@@ -2121,6 +2159,10 @@ nv50_disp_atomic_check(struct drm_device *dev, struct 
drm_atomic_state *state)
return ret;
}
 
+   ret = drm_dp_mst_atomic_check(state);
+   if (ret)
+   return ret;
+
return 0;
 }
 
-- 
2.20.1

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


[PATCH v5 16/20] drm/nouveau: Grab payload lock in nv50_msto_payload()

2019-01-08 Thread Lyude Paul
Going through the currently programmed payloads isn't safe without
holding mgr->payload_lock, so actually do that and warn if anyone tries
calling nv50_msto_payload() in the future without grabbing the right
locks.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 157d208d37b5..67f7bf97e5d9 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -680,6 +680,8 @@ nv50_msto_payload(struct nv50_msto *msto)
struct nv50_mstm *mstm = mstc->mstm;
int vcpi = mstc->port->vcpi.vcpi, i;
 
+   WARN_ON(!mutex_is_locked(>mgr.payload_lock));
+
NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi);
for (i = 0; i < mstm->mgr.max_payloads; i++) {
struct drm_dp_payload *payload = >mgr.payloads[i];
@@ -733,6 +735,8 @@ nv50_msto_prepare(struct nv50_msto *msto)
   (0x0100 << msto->head->base.index),
};
 
+   mutex_lock(>mgr.payload_lock);
+
NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
if (mstc->port->vcpi.vcpi > 0) {
struct drm_dp_payload *payload = nv50_msto_payload(msto);
@@ -748,7 +752,9 @@ nv50_msto_prepare(struct nv50_msto *msto)
  msto->encoder.name, msto->head->base.base.name,
  args.vcpi.start_slot, args.vcpi.num_slots,
  args.vcpi.pbn, args.vcpi.aligned_pbn);
+
nvif_mthd(>display->disp.object, 0, , sizeof(args));
+   mutex_unlock(>mgr.payload_lock);
 }
 
 static int
-- 
2.20.1

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


[PATCH v5 14/20] drm/nouveau: Keep malloc references to MST ports

2019-01-08 Thread Lyude Paul
Now that we finally have a sane way to keep port allocations around, use
it to fix the potential unchecked ->port accesses that nouveau makes by
making sure we keep the mst port allocated for as long as it's
drm_connector is accessible.

Additionally, now that we've guaranteed that mstc->port is allocated for
as long as we keep mstc around we can remove the connector registration
checks for codepaths which release payloads, allowing us to release
payloads on active topologies properly. These registration checks were
only required before in order to avoid situations where mstc->port could
technically be pointing at freed memory.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 0f7d72518604..982054bbcc8b 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -964,7 +964,11 @@ static void
 nv50_mstc_destroy(struct drm_connector *connector)
 {
struct nv50_mstc *mstc = nv50_mstc(connector);
+
drm_connector_cleanup(>connector);
+   if (mstc->port)
+   drm_dp_mst_put_port_malloc(mstc->port);
+
kfree(mstc);
 }
 
@@ -1012,6 +1016,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct 
drm_dp_mst_port *port,
drm_object_attach_property(>connector.base, 
dev->mode_config.path_property, 0);
drm_object_attach_property(>connector.base, 
dev->mode_config.tile_property, 0);
drm_connector_set_path_property(>connector, path);
+   drm_dp_mst_get_port_malloc(port);
return 0;
 }
 
@@ -1077,6 +1082,7 @@ nv50_mstm_destroy_connector(struct 
drm_dp_mst_topology_mgr *mgr,
drm_fb_helper_remove_one_connector(>fbcon->helper, 
>connector);
 
drm_modeset_lock(>dev->mode_config.connection_mutex, NULL);
+   drm_dp_mst_put_port_malloc(mstc->port);
mstc->port = NULL;
drm_modeset_unlock(>dev->mode_config.connection_mutex);
 
-- 
2.20.1

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


[PATCH v5 10/20] drm/i915: Keep malloc references to MST ports

2019-01-08 Thread Lyude Paul
So that the ports stay around until we've destroyed the connectors, in
order to ensure that we don't pass an invalid pointer to any MST helpers
once we introduce the new MST VCPI helpers.

Changes since v1:
* Move drm_dp_mst_get_port_malloc() to where we assign
  intel_connector->port - danvet

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/i915/intel_connector.c | 4 
 drivers/gpu/drm/i915/intel_dp_mst.c| 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_connector.c 
b/drivers/gpu/drm/i915/intel_connector.c
index 18e370f607bc..37d2c644f4b8 100644
--- a/drivers/gpu/drm/i915/intel_connector.c
+++ b/drivers/gpu/drm/i915/intel_connector.c
@@ -95,6 +95,10 @@ void intel_connector_destroy(struct drm_connector *connector)
intel_panel_fini(_connector->panel);
 
drm_connector_cleanup(connector);
+
+   if (intel_connector->port)
+   drm_dp_mst_put_port_malloc(intel_connector->port);
+
kfree(connector);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index f05427b74e34..631fd1537252 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -457,6 +457,7 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
intel_connector->mst_port = intel_dp;
intel_connector->port = port;
+   drm_dp_mst_get_port_malloc(port);
 
connector = _connector->base;
ret = drm_connector_init(dev, connector, _dp_mst_connector_funcs,
-- 
2.20.1

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


[PATCH v5 19/20] drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()

2019-01-08 Thread Lyude Paul
It occurred to me that we never actually check this! So let's start
doing that.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index fc778c6d487e..41cf814207bf 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3650,7 +3650,7 @@ drm_dp_mst_atomic_check_topology_state(struct 
drm_dp_mst_topology_mgr *mgr,
   struct drm_dp_mst_topology_state 
*mst_state)
 {
struct drm_dp_vcpi_allocation *vcpi;
-   int avail_slots = 63;
+   int avail_slots = 63, payload_count = 0;
 
list_for_each_entry(vcpi, _state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -3670,6 +3670,12 @@ drm_dp_mst_atomic_check_topology_state(struct 
drm_dp_mst_topology_mgr *mgr,
 avail_slots + vcpi->vcpi);
return -ENOSPC;
}
+
+   if (++payload_count > mgr->max_payloads) {
+   DRM_DEBUG_ATOMIC("[MST MGR:%p] state %p has too many 
payloads (max=%d)\n",
+mgr, mst_state, mgr->max_payloads);
+   return -EINVAL;
+   }
}
DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
 mgr, mst_state, avail_slots,
-- 
2.20.1

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


[PATCH v5 17/20] drm/dp_mst: Add some atomic state iterator macros

2019-01-08 Thread Lyude Paul
Changes since v6:
 - Move EXPORT_SYMBOL() for drm_dp_mst_topology_state_funcs to this
   commit
 - Document __drm_dp_mst_state_iter_get() and note that it shouldn't be
   called directly

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c |  5 +-
 include/drm/drm_dp_mst_helper.h   | 96 +++
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index efd8fa29fff6..370371145cdd 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3530,10 +3530,11 @@ static void drm_dp_mst_destroy_state(struct 
drm_private_obj *obj,
kfree(mst_state);
 }
 
-static const struct drm_private_state_funcs mst_state_funcs = {
+const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = {
.atomic_duplicate_state = drm_dp_mst_duplicate_state,
.atomic_destroy_state = drm_dp_mst_destroy_state,
 };
+EXPORT_SYMBOL(drm_dp_mst_topology_state_funcs);
 
 /**
  * drm_atomic_get_mst_topology_state: get MST topology state
@@ -3617,7 +3618,7 @@ int drm_dp_mst_topology_mgr_init(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_atomic_private_obj_init(dev, >base,
_state->base,
-   _state_funcs);
+   _dp_mst_topology_state_funcs);
 
return 0;
 }
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 8eca5f29242c..581163c8d7d7 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -650,4 +650,100 @@ int drm_dp_send_power_updown_phy(struct 
drm_dp_mst_topology_mgr *mgr,
 void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
 void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port);
 
+extern const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs;
+
+/**
+ * __drm_dp_mst_state_iter_get - private atomic state iterator function for
+ * macro-internal use
+ * @state:  drm_atomic_state pointer
+ * @mgr: pointer to the  drm_dp_mst_topology_mgr iteration cursor
+ * @old_state: optional pointer to the old  drm_dp_mst_topology_state
+ * iteration cursor
+ * @new_state: optional pointer to the new  drm_dp_mst_topology_state
+ * iteration cursor
+ * @i: int iteration cursor, for macro-internal use
+ *
+ * Used by for_each_oldnew_mst_mgr_in_state(),
+ * for_each_old_mst_mgr_in_state(), and for_each_new_mst_mgr_in_state(). Don't
+ * call this directly.
+ *
+ * Returns:
+ * True if the current  drm_private_obj is a 
+ * drm_dp_mst_topology_mgr, false otherwise.
+ */
+static inline bool
+__drm_dp_mst_state_iter_get(struct drm_atomic_state *state,
+   struct drm_dp_mst_topology_mgr **mgr,
+   struct drm_dp_mst_topology_state **old_state,
+   struct drm_dp_mst_topology_state **new_state,
+   int i)
+{
+   struct __drm_private_objs_state *objs_state = >private_objs[i];
+
+   if (objs_state->ptr->funcs != _dp_mst_topology_state_funcs)
+   return false;
+
+   *mgr = to_dp_mst_topology_mgr(objs_state->ptr);
+   if (old_state)
+   *old_state = to_dp_mst_topology_state(objs_state->old_state);
+   if (new_state)
+   *new_state = to_dp_mst_topology_state(objs_state->new_state);
+
+   return true;
+}
+
+/**
+ * for_each_oldnew_mst_mgr_in_state - iterate over all DP MST topology
+ * managers in an atomic update
+ * @__state:  drm_atomic_state pointer
+ * @mgr:  drm_dp_mst_topology_mgr iteration cursor
+ * @old_state:  drm_dp_mst_topology_state iteration cursor for the old
+ * state
+ * @new_state:  drm_dp_mst_topology_state iteration cursor for the new
+ * state
+ * @__i: int iteration cursor, for macro-internal use
+ *
+ * This iterates over all DRM DP MST topology managers in an atomic update,
+ * tracking both old and new state. This is useful in places where the state
+ * delta needs to be considered, for example in atomic check functions.
+ */
+#define for_each_oldnew_mst_mgr_in_state(__state, mgr, old_state, new_state, 
__i) \
+   for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \
+   for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), 
&(old_state), &(new_state), (__i)))
+
+/**
+ * for_each_old_mst_mgr_in_state - iterate over all DP MST topology managers
+ * in an atomic update
+ * @__state:  drm_atomic_state pointer
+ * @mgr:  drm_dp_mst_topology_mgr iteration cursor
+ * @old_state:  drm_dp_mst_topology_state iteration cursor for the old
+ * state
+ * @__i: int iteration cursor, for macro-internal use
+ *
+ * This iterates over all DRM DP MST topology managers in an atomic update,
+ * tracking only the old state. This is useful in disable functions, where we
+ * need the old 

[PATCH v5 11/20] drm/amdgpu/display: Keep malloc ref to MST port

2019-01-08 Thread Lyude Paul
Just like i915 and nouveau, it's a good idea for us to hold a malloc
reference to the port here so that we never pass a freed pointer to any
of the DP MST helper functions.

Also, we stop unsetting aconnector->port in
dm_dp_destroy_mst_connector(). There's literally no point to that
assignment that I can see anyway.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5e7ca1f3a8d1..24632727e127 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -191,6 +191,7 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
drm_encoder_cleanup(_encoder->base);
kfree(amdgpu_encoder);
drm_connector_cleanup(connector);
+   drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
kfree(amdgpu_dm_connector);
 }
 
@@ -363,7 +364,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
amdgpu_dm_connector_funcs_reset(connector);
 
DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
-   aconnector, connector->base.id, aconnector->mst_port);
+aconnector, connector->base.id, aconnector->mst_port);
+
+   drm_dp_mst_get_port_malloc(port);
 
DRM_DEBUG_KMS(":%d\n", connector->base.id);
 
@@ -379,12 +382,12 @@ static void dm_dp_destroy_mst_connector(struct 
drm_dp_mst_topology_mgr *mgr,
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
 
DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
-   aconnector, connector->base.id, 
aconnector->mst_port);
+aconnector, connector->base.id, aconnector->mst_port);
 
-   aconnector->port = NULL;
if (aconnector->dc_sink) {
amdgpu_dm_update_freesync_caps(connector, NULL);
-   dc_link_remove_remote_sink(aconnector->dc_link, 
aconnector->dc_sink);
+   dc_link_remove_remote_sink(aconnector->dc_link,
+  aconnector->dc_sink);
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
}
-- 
2.20.1

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


[PATCH v5 08/20] drm/dp_mst: Stop releasing VCPI when removing ports from topology

2019-01-08 Thread Lyude Paul
This has never actually worked, and isn't needed anyway: the driver's
always going to try to deallocate VCPI when it tears down the display
that the VCPI belongs to.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index bafc85f08606..8088527a7aea 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1176,8 +1176,6 @@ static void drm_dp_destroy_port(struct kref *kref)
struct drm_dp_mst_topology_mgr *mgr = port->mgr;
 
if (!port->input) {
-   port->vcpi.num_slots = 0;
-
kfree(port->cached_edid);
 
/*
@@ -3496,12 +3494,6 @@ static void drm_dp_destroy_connector_work(struct 
work_struct *work)
drm_dp_port_teardown_pdt(port, port->pdt);
port->pdt = DP_PEER_DEVICE_NONE;
 
-   if (!port->input && port->vcpi.vcpi > 0) {
-   drm_dp_mst_reset_vcpi_slots(mgr, port);
-   drm_dp_update_payload_part1(mgr);
-   drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
-   }
-
drm_dp_mst_put_port_malloc(port);
send_hotplug = true;
}
-- 
2.20.1

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


[PATCH v5 05/20] drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and friends

2019-01-08 Thread Lyude Paul
s/drm_dp_get_validated_port_ref/drm_dp_mst_topology_get_port_validated/
s/drm_dp_put_port/drm_dp_mst_topology_put_port/
s/drm_dp_get_validated_mstb_ref/drm_dp_mst_topology_get_mstb_validated/
s/drm_dp_put_mst_branch_device/drm_dp_mst_topology_put_mstb/

This is a much more consistent naming scheme, and will make even more
sense once we redesign how the current refcounting scheme here works.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Reviewed-by: Harry Wentland 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 114 ++
 1 file changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 75cca6a843fb..074e985093ca 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -46,7 +46,7 @@ static bool dump_dp_payload_table(struct 
drm_dp_mst_topology_mgr *mgr,
  char *buf);
 static int test_calc_pbn_mode(void);
 
-static void drm_dp_put_port(struct drm_dp_mst_port *port);
+static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);
 
 static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
 int id,
@@ -888,7 +888,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref 
*kref)
 */
list_for_each_entry_safe(port, tmp, >ports, next) {
list_del(>next);
-   drm_dp_put_port(port);
+   drm_dp_mst_topology_put_port(port);
}
 
/* drop any tx slots msg */
@@ -911,7 +911,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref 
*kref)
kref_put(kref, drm_dp_free_mst_branch_device);
 }
 
-static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb)
+static void drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)
 {
kref_put(>kref, drm_dp_destroy_mst_branch_device);
 }
@@ -930,7 +930,7 @@ static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port 
*port, int old_pdt)
case DP_PEER_DEVICE_MST_BRANCHING:
mstb = port->mstb;
port->mstb = NULL;
-   drm_dp_put_mst_branch_device(mstb);
+   drm_dp_mst_topology_put_mstb(mstb);
break;
}
 }
@@ -970,12 +970,14 @@ static void drm_dp_destroy_port(struct kref *kref)
kfree(port);
 }
 
-static void drm_dp_put_port(struct drm_dp_mst_port *port)
+static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)
 {
kref_put(>kref, drm_dp_destroy_port);
 }
 
-static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct drm_dp_mst_branch *mstb, 
struct drm_dp_mst_branch *to_find)
+static struct drm_dp_mst_branch *
+drm_dp_mst_topology_get_mstb_validated_locked(struct drm_dp_mst_branch *mstb,
+ struct drm_dp_mst_branch *to_find)
 {
struct drm_dp_mst_port *port;
struct drm_dp_mst_branch *rmstb;
@@ -985,7 +987,8 @@ static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct
}
list_for_each_entry(port, >ports, next) {
if (port->mstb) {
-   rmstb = 
drm_dp_mst_get_validated_mstb_ref_locked(port->mstb, to_find);
+   rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
+   port->mstb, to_find);
if (rmstb)
return rmstb;
}
@@ -993,12 +996,15 @@ static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct
return NULL;
 }
 
-static struct drm_dp_mst_branch *drm_dp_get_validated_mstb_ref(struct 
drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb)
+static struct drm_dp_mst_branch *
+drm_dp_mst_topology_get_mstb_validated(struct drm_dp_mst_topology_mgr *mgr,
+  struct drm_dp_mst_branch *mstb)
 {
struct drm_dp_mst_branch *rmstb = NULL;
mutex_lock(>lock);
if (mgr->mst_primary)
-   rmstb = 
drm_dp_mst_get_validated_mstb_ref_locked(mgr->mst_primary, mstb);
+   rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
+   mgr->mst_primary, mstb);
mutex_unlock(>lock);
return rmstb;
 }
@@ -1021,7 +1027,9 @@ static struct drm_dp_mst_port 
*drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_
return NULL;
 }
 
-static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct 
drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+static struct drm_dp_mst_port *
+drm_dp_mst_topology_get_port_validated(struct drm_dp_mst_topology_mgr *mgr,
+  struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_port *rport = NULL;
mutex_lock(>lock);
@@ -1215,7 +1223,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch 
*mstb,
 

[PATCH v5 13/20] drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()

2019-01-08 Thread Lyude Paul
There is no need to look at the port's VCPI allocation before calling
drm_dp_mst_deallocate_vcpi(), as we already have msto->disabled to let
us avoid cleaning up an msto more then once. The DP MST core will never
call drm_dp_mst_deallocate_vcpi() on it's own, which is presumably what
these checks are meant to protect against.

More importantly though, we're about to stop clearing mstc->port in the
next commit, which means if we could potentially hit a use-after-free
error if we tried to check mstc->port->vcpi here. So to make life easier
for anyone who bisects this code in the future, use msto->disabled
instead to check whether or not we need to deallocate VCPI instead.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 641252208e67..0f7d72518604 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -704,14 +704,17 @@ nv50_msto_cleanup(struct nv50_msto *msto)
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
 
+   if (!msto->disabled)
+   return;
+
NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
-   if (mstc->port && mstc->port->vcpi.vcpi > 0 && !nv50_msto_payload(msto))
+
+   if (mstc->port)
drm_dp_mst_deallocate_vcpi(>mgr, mstc->port);
-   if (msto->disabled) {
-   msto->mstc = NULL;
-   msto->head = NULL;
-   msto->disabled = false;
-   }
+
+   msto->mstc = NULL;
+   msto->head = NULL;
+   msto->disabled = false;
 }
 
 static void
-- 
2.20.1

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


[PATCH v5 15/20] drm/nouveau: Stop unsetting mstc->port, use malloc refs

2019-01-08 Thread Lyude Paul
Same as we did for i915, but for nouveau this time. Additionally, we
grab a malloc reference to the port that lasts for the entire lifetime
of nv50_mstc, which gives us the guarantee that mstc->port will always
point to valid memory for as long as the mstc stays around.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 982054bbcc8b..157d208d37b5 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -709,8 +709,7 @@ nv50_msto_cleanup(struct nv50_msto *msto)
 
NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
-   if (mstc->port)
-   drm_dp_mst_deallocate_vcpi(>mgr, mstc->port);
+   drm_dp_mst_deallocate_vcpi(>mgr, mstc->port);
 
msto->mstc = NULL;
msto->head = NULL;
@@ -735,7 +734,7 @@ nv50_msto_prepare(struct nv50_msto *msto)
};
 
NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
-   if (mstc->port && mstc->port->vcpi.vcpi > 0) {
+   if (mstc->port->vcpi.vcpi > 0) {
struct drm_dp_payload *payload = nv50_msto_payload(msto);
if (payload) {
args.vcpi.start_slot = payload->start_slot;
@@ -832,8 +831,7 @@ nv50_msto_disable(struct drm_encoder *encoder)
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
 
-   if (mstc->port)
-   drm_dp_mst_reset_vcpi_slots(>mgr, mstc->port);
+   drm_dp_mst_reset_vcpi_slots(>mgr, mstc->port);
 
mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0);
mstm->modified = true;
@@ -945,7 +943,7 @@ nv50_mstc_detect(struct drm_connector *connector, bool 
force)
enum drm_connector_status conn_status;
int ret;
 
-   if (!mstc->port)
+   if (drm_connector_is_unregistered(connector))
return connector_status_disconnected;
 
ret = pm_runtime_get_sync(connector->dev->dev);
@@ -966,8 +964,7 @@ nv50_mstc_destroy(struct drm_connector *connector)
struct nv50_mstc *mstc = nv50_mstc(connector);
 
drm_connector_cleanup(>connector);
-   if (mstc->port)
-   drm_dp_mst_put_port_malloc(mstc->port);
+   drm_dp_mst_put_port_malloc(mstc->port);
 
kfree(mstc);
 }
@@ -1081,11 +1078,6 @@ nv50_mstm_destroy_connector(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_fb_helper_remove_one_connector(>fbcon->helper, 
>connector);
 
-   drm_modeset_lock(>dev->mode_config.connection_mutex, NULL);
-   drm_dp_mst_put_port_malloc(mstc->port);
-   mstc->port = NULL;
-   drm_modeset_unlock(>dev->mode_config.connection_mutex);
-
drm_connector_put(>connector);
 }
 
-- 
2.20.1

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


[PATCH v5 12/20] drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()

2019-01-08 Thread Lyude Paul
Trying to destroy the connector using mstc->connector.funcs->destroy()
if connector initialization fails is wrong: there is no possible
codepath in nv50_mstc_new where nv50_mstm_add_connector() would return
<0 and mstc would be non-NULL.

Signed-off-by: Lyude Paul 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 26af45785939..641252208e67 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1099,11 +1099,8 @@ nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr 
*mgr,
int ret;
 
ret = nv50_mstc_new(mstm, port, path, );
-   if (ret) {
-   if (mstc)
-   mstc->connector.funcs->destroy(>connector);
+   if (ret)
return NULL;
-   }
 
return >connector;
 }
-- 
2.20.1

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


[PATCH v5 07/20] drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref fails

2019-01-08 Thread Lyude Paul
While this isn't a complete fix, this will improve the reliability of
drm_dp_get_last_connected_port_and_mstb() pretty significantly during
hotplug events, since there's a chance that the in-memory topology tree
may not be fully updated when drm_dp_get_last_connected_port_and_mstb()
is called and thus might end up causing our search to fail on an mstb
whose topology refcount has reached 0, but has not yet been removed from
it's parent.

Ideally, we should further fix this problem by ensuring that we deal
with the potential for racing with a hotplug event, which would look
like this:

* drm_dp_payload_send_msg() retrieves the last living relative of mstb
  with drm_dp_get_last_connected_port_and_mstb()
* drm_dp_payload_send_msg() starts building payload message
  At the same time, mstb gets unplugged from the topology and is no
  longer the actual last living relative of the original mstb
* drm_dp_payload_send_msg() tries sending the payload message, hub times
  out
* Hub timed out, we give up and run away-resulting in the payload being
  leaked

This could be fixed by restarting the
drm_dp_get_last_connected_port_and_mstb() search whenever we get a
timeout, sending the payload to the new mstb, then repeating until
either the entire topology is removed from the system or
drm_dp_get_last_connected_port_and_mstb() fails. But since the above
race condition is not terribly likely, we'll address that in a later
patch series once we've improved the recovery handling for VCPI
allocations in the rest of the DP MST helpers.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 54 ++-
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index c53cf7eb1dbc..bafc85f08606 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2047,24 +2047,50 @@ static struct drm_dp_mst_port 
*drm_dp_get_last_connected_port_to_mstb(struct drm
return 
drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
 }
 
-static struct drm_dp_mst_branch 
*drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
-struct 
drm_dp_mst_branch *mstb,
-int 
*port_num)
+/**
+ * drm_dp_get_last_connected_port_and_mstb() - Find the last living relatives
+ * in a topology of a given branch device
+ * @mgr: The topology manager to use
+ * @mstb: The disconnected branch device
+ * @port_num: Where to store the number of the last connected port
+ *
+ * Searches upwards in the topology starting from @mstb to try to find the
+ * closest available parent of @mstb that's still connected to the rest of the
+ * topology. This can be used in order to perform operations like releasing
+ * payloads, where the branch device which owned the payload may no longer be
+ * around and thus would require that the payload on the last living relative
+ * be freed instead.
+ *
+ * Returns:
+ * The last connected _dp_mst_branch in the topology that was a parent of
+ * @mstb, if there is one.
+ */
+static struct drm_dp_mst_branch *
+drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
+   struct drm_dp_mst_branch *mstb,
+   int *port_num)
 {
struct drm_dp_mst_branch *rmstb = NULL;
struct drm_dp_mst_port *found_port;
+
mutex_lock(>lock);
-   if (mgr->mst_primary) {
+   if (!mgr->mst_primary)
+   goto out;
+
+   do {
found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
+   if (!found_port)
+   break;
 
-   if (found_port) {
+   if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
rmstb = found_port->parent;
-   if (drm_dp_mst_topology_try_get_mstb(rmstb))
-   *port_num = found_port->port_num;
-   else
-   rmstb = NULL;
+   *port_num = found_port->port_num;
+   } else {
+   /* Search again, starting from this parent */
+   mstb = found_port->parent;
}
-   }
+   } while (!rmstb);
+out:
mutex_unlock(>lock);
return rmstb;
 }
@@ -2113,6 +2139,14 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_dp_queue_down_tx(mgr, txmsg);
 
+   /*
+* FIXME: there is a small chance that between getting the last
+* connected mstb and sending the payload message, the last connected
+* mstb could also be removed from the topology. In the 

[PATCH v5 04/20] drm/dp_mst: Fix some formatting in drm_dp_mst_deallocate_vcpi()

2019-01-08 Thread Lyude Paul
Split some stuff across multiple lines

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index a63a4d32962a..75cca6a843fb 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2790,7 +2790,8 @@ EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
  * @mgr: manager for this port
  * @port: unverified port to deallocate vcpi for
  */
-void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct 
drm_dp_mst_port *port)
+void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
+   struct drm_dp_mst_port *port)
 {
port = drm_dp_get_validated_port_ref(mgr, port);
if (!port)
-- 
2.20.1

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


[PATCH v5 02/20] drm/dp_mst: Fix some formatting in drm_dp_payload_send_msg()

2019-01-08 Thread Lyude Paul
Split some stuff across multiple lines, remove some unnecessary braces

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index c93bff5527fd..fc93a71c42b0 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1331,9 +1331,9 @@ static struct drm_dp_mst_branch 
*get_mst_branch_device_by_guid_helper(
return NULL;
 }
 
-static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid(
-   struct drm_dp_mst_topology_mgr *mgr,
-   uint8_t *guid)
+static struct drm_dp_mst_branch *
+drm_dp_get_mst_branch_device_by_guid(struct drm_dp_mst_topology_mgr *mgr,
+uint8_t *guid)
 {
struct drm_dp_mst_branch *mstb;
 
@@ -1739,7 +1739,9 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
port_num = port->port_num;
mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
if (!mstb) {
-   mstb = drm_dp_get_last_connected_port_and_mstb(mgr, 
port->parent, _num);
+   mstb = drm_dp_get_last_connected_port_and_mstb(mgr,
+  port->parent,
+  _num);
 
if (!mstb) {
drm_dp_put_port(port);
@@ -1765,9 +1767,9 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
 
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
if (ret > 0) {
-   if (txmsg->reply.reply_type == 1) {
+   if (txmsg->reply.reply_type == 1)
ret = -EINVAL;
-   } else
+   else
ret = 0;
}
kfree(txmsg);
-- 
2.20.1

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


[PATCH v5 00/20] MST refcounting/atomic helpers cleanup

2019-01-08 Thread Lyude Paul
This is the series I've been working on for a while now to get all of
the atomic DRM drivers in the tree to use the atomic MST helpers, and to
make the atomic MST helpers actually idempotent. Turns out it's a lot
more difficult to do that without also fixing how port and branch device
refcounting works so that it actually makes sense, since the current
upstream implementation requires a ton of magic in the atomic helpers to
work around properly and in many situations just plain doesn't work as
intended.

There's still more cleanup that can be done, but I think this is a good
place to start off for now :).

Also available on gitlab:

https://gitlab.freedesktop.org/lyudess/linux/commits/wip/mst-dual-kref-start-v5

Cc: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 

Lyude Paul (20):
  drm/dp_mst: Fix some formatting in drm_dp_add_port()
  drm/dp_mst: Fix some formatting in drm_dp_payload_send_msg()
  drm/dp_mst: Fix some formatting in drm_dp_mst_allocate_vcpi()
  drm/dp_mst: Fix some formatting in drm_dp_mst_deallocate_vcpi()
  drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and
friends
  drm/dp_mst: Introduce new refcounting scheme for mstbs and ports
  drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref
fails
  drm/dp_mst: Stop releasing VCPI when removing ports from topology
  drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs
  drm/i915: Keep malloc references to MST ports
  drm/amdgpu/display: Keep malloc ref to MST port
  drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()
  drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()
  drm/nouveau: Keep malloc references to MST ports
  drm/nouveau: Stop unsetting mstc->port, use malloc refs
  drm/nouveau: Grab payload lock in nv50_msto_payload()
  drm/dp_mst: Add some atomic state iterator macros
  drm/dp_mst: Start tracking per-port VCPI allocations
  drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()
  drm/nouveau: Use atomic VCPI helpers for MST

 .../gpu/dp-mst/topology-figure-1.dot  |  52 +
 .../gpu/dp-mst/topology-figure-2.dot  |  56 +
 .../gpu/dp-mst/topology-figure-3.dot  |  59 ++
 Documentation/gpu/drm-kms-helpers.rst |  26 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  11 +-
 drivers/gpu/drm/drm_dp_mst_topology.c | 955 ++
 drivers/gpu/drm/i915/intel_connector.c|   4 +
 drivers/gpu/drm/i915/intel_display.c  |   4 +
 drivers/gpu/drm/i915/intel_dp_mst.c   |  55 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  96 +-
 include/drm/drm_dp_mst_helper.h   | 151 ++-
 11 files changed, 1213 insertions(+), 256 deletions(-)
 create mode 100644 Documentation/gpu/dp-mst/topology-figure-1.dot
 create mode 100644 Documentation/gpu/dp-mst/topology-figure-2.dot
 create mode 100644 Documentation/gpu/dp-mst/topology-figure-3.dot

-- 
2.20.1

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


[PATCH v5 06/20] drm/dp_mst: Introduce new refcounting scheme for mstbs and ports

2019-01-08 Thread Lyude Paul
The current way of handling refcounting in the DP MST helpers is really
confusing and probably just plain wrong because it's been hacked up many
times over the years without anyone actually going over the code and
seeing if things could be simplified.

To the best of my understanding, the current scheme works like this:
drm_dp_mst_port and drm_dp_mst_branch both have a single refcount. When
this refcount hits 0 for either of the two, they're removed from the
topology state, but not immediately freed. Both ports and branch devices
will reinitialize their kref once it's hit 0 before actually destroying
themselves. The intended purpose behind this is so that we can avoid
problems like not being able to free a remote payload that might still
be active, due to us having removed all of the port/branch device
structures in memory, as per:

commit 91a25e463130 ("drm/dp/mst: deallocate payload on port destruction")

Which may have worked, but then it caused use-after-free errors. Being
new to MST at the time, I tried fixing it;

commit 263efde31f97 ("drm/dp/mst: Get validated port ref in 
drm_dp_update_payload_part1()")

But, that was broken: both drm_dp_mst_port and drm_dp_mst_branch structs
are validated in almost every DP MST helper function. Simply put, this
means we go through the topology and try to see if the given
drm_dp_mst_branch or drm_dp_mst_port is still attached to something
before trying to use it in order to avoid dereferencing freed memory
(something that has happened a LOT in the past with this library).
Because of this it doesn't actually matter whether or not we keep keep
the ports and branches around in memory as that's not enough, because
any function that validates the branches and ports passed to it will
still reject them anyway since they're no longer in the topology
structure. So, use-after-free errors were fixed but payload deallocation
was completely broken.

Two years later, AMD informed me about this issue and I attempted to
come up with a temporary fix, pending a long-overdue cleanup of this
library:

commit c54c7374ff44 ("drm/dp_mst: Skip validating ports during destruction, 
just ref")

But then that introduced use-after-free errors, so I quickly reverted
it:

commit 9765635b3075 ("Revert "drm/dp_mst: Skip validating ports during 
destruction, just ref"")

And in the process, learned that there is just no simple fix for this:
the design is just broken. Unfortunately, the usage of these helpers are
quite broken as well. Some drivers like i915 have been smart enough to
avoid accessing any kind of information from MST port structures, but
others like nouveau have assumed, understandably so, that
drm_dp_mst_port structures are normal and can just be accessed at any
time without worrying about use-after-free errors.

After a lot of discussion, me and Daniel Vetter came up with a better
idea to replace all of this.

To summarize, since this is documented far more indepth in the
documentation this patch introduces, we make it so that drm_dp_mst_port
and drm_dp_mst_branch structures have two different classes of
refcounts: topology_kref, and malloc_kref. topology_kref corresponds to
the lifetime of the given drm_dp_mst_port or drm_dp_mst_branch in it's
given topology. Once it hits zero, any associated connectors are removed
and the branch or port can no longer be validated. malloc_kref
corresponds to the lifetime of the memory allocation for the actual
structure, and will always be non-zero so long as the topology_kref is
non-zero. This gives us a way to allow callers to hold onto port and
branch device structures past their topology lifetime, and dramatically
simplifies the lifetimes of both structures. This also finally fixes the
port deallocation problem, properly.

Additionally: since this now means that we can keep ports and branch
devices allocated in memory for however long we need, we no longer need
a significant amount of the port validation that we currently do.

Additionally, there is one last scenario that this fixes, which couldn't
have been fixed properly beforehand:

- CPU1 unrefs port from topology (refcount 1->0)
- CPU2 refs port in topology(refcount 0->1)

Since we now can guarantee memory safety for ports and branches
as-needed, we also can make our main reference counting functions fix
this problem by using kref_get_unless_zero() internally so that topology
refcounts can only ever reach 0 once.

Changes since v3:
* Remove rebase detritus - danvet
* Split out purely style changes into separate patches - hwentlan

Changes since v2:
* Fix commit message - checkpatch
* s/)-1/) - 1/g - checkpatch

Changes since v1:
* Remove forward declarations - danvet
* Move "Branch device and port refcounting" section from documentation
  into kernel-doc comments - danvet
* Export internal topology lifetime functions into their own section in
  the kernel-docs - danvet
* s/@/&/g for struct references in kernel-docs - danvet
* Drop the "when they are no longer being used" bits from the 

[PATCH v5 03/20] drm/dp_mst: Fix some formatting in drm_dp_mst_allocate_vcpi()

2019-01-08 Thread Lyude Paul
Fix some indenting, split some stuff across multiple lines.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index fc93a71c42b0..a63a4d32962a 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2731,7 +2731,8 @@ bool drm_dp_mst_allocate_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
return false;
 
if (port->vcpi.vcpi > 0) {
-   DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - 
requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn);
+   DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - 
requested pbn %d\n",
+ port->vcpi.vcpi, port->vcpi.pbn, pbn);
if (pbn == port->vcpi.pbn) {
drm_dp_put_port(port);
return true;
@@ -2741,11 +2742,11 @@ bool drm_dp_mst_allocate_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
ret = drm_dp_init_vcpi(mgr, >vcpi, pbn, slots);
if (ret) {
DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
-   DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
+ DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
goto out;
}
DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
-   pbn, port->vcpi.num_slots);
+ pbn, port->vcpi.num_slots);
 
drm_dp_put_port(port);
return true;
-- 
2.20.1

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


[PATCH v5 01/20] drm/dp_mst: Fix some formatting in drm_dp_add_port()

2019-01-08 Thread Lyude Paul
Reindent some stuff, and split some stuff across multiple lines so we
aren't going over the text width limit.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 2ab16c9e6243..c93bff5527fd 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1184,11 +1184,13 @@ static void drm_dp_add_port(struct drm_dp_mst_branch 
*mstb,
 
if (old_ddps != port->ddps) {
if (port->ddps) {
-   if (!port->input)
-   drm_dp_send_enum_path_resources(mstb->mgr, 
mstb, port);
+   if (!port->input) {
+   drm_dp_send_enum_path_resources(mstb->mgr,
+   mstb, port);
+   }
} else {
port->available_pbn = 0;
-   }
+   }
}
 
if (old_pdt != port->pdt && !port->input) {
@@ -1202,8 +1204,11 @@ static void drm_dp_add_port(struct drm_dp_mst_branch 
*mstb,
if (created && !port->input) {
char proppath[255];
 
-   build_mst_prop_path(mstb, port->port_num, proppath, 
sizeof(proppath));
-   port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, 
port, proppath);
+   build_mst_prop_path(mstb, port->port_num, proppath,
+   sizeof(proppath));
+   port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr,
+  port,
+  proppath);
if (!port->connector) {
/* remove it from the port list */
mutex_lock(>mgr->lock);
@@ -1216,7 +1221,8 @@ static void drm_dp_add_port(struct drm_dp_mst_branch 
*mstb,
if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
 port->pdt == DP_PEER_DEVICE_SST_SINK) &&
port->port_num >= DP_MST_LOGICAL_PORT_0) {
-   port->cached_edid = drm_get_edid(port->connector, 
>aux.ddc);
+   port->cached_edid = drm_get_edid(port->connector,
+>aux.ddc);
drm_connector_set_tile_property(port->connector);
}
(*mstb->mgr->cbs->register_connector)(port->connector);
-- 
2.20.1

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


[PATCH 1/1] drm/amdkfd: Don't assign dGPUs to APU topology devices

2019-01-08 Thread Kuehling, Felix
dGPUs need their own topology devices. Don't assign them to APU topology
devices with CPU cores.

Bug: https://github.com/RadeonOpenCompute/ROCK-Kernel-Driver/issues/66
Signed-off-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 4734f1a..09da916 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1093,8 +1093,6 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu)
  * the GPU device is not already present in the topology device
  * list then return NULL. This means a new topology device has to
  * be created for this GPU.
- * TODO: Rather than assiging @gpu to first topology device withtout
- * gpu attached, it will better to have more stringent check.
  */
 static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
 {
@@ -1102,12 +1100,20 @@ static struct kfd_topology_device 
*kfd_assign_gpu(struct kfd_dev *gpu)
struct kfd_topology_device *out_dev = NULL;
 
down_write(_lock);
-   list_for_each_entry(dev, _device_list, list)
+   list_for_each_entry(dev, _device_list, list) {
+   /* Discrete GPUs need their own topology device list
+* entries. Don't assign them to CPU/APU nodes.
+*/
+   if (!gpu->device_info->needs_iommu_device &&
+   dev->node_props.cpu_cores_count)
+   continue;
+
if (!dev->gpu && (dev->node_props.simd_count > 0)) {
dev->gpu = gpu;
out_dev = dev;
break;
}
+   }
up_write(_lock);
return out_dev;
 }
-- 
2.7.4

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


Re: [PATCH 0/6] kexec fixes

2019-01-08 Thread Kuehling, Felix
Thanks for this. I trust that your method for detecting that SMU or PSP
are running is correct. With that caveat the series is Reviewed-by:
Felix Kuehling 

Regards,
  Felix

On 2019-01-08 5:11 p.m., Alex Deucher wrote:
> Fixes for kexec.  The GPU needs to be reset before the driver
> can be loaded again reliably.  Needed for kexec for booting some
> ppc platforms.  See:
> https://bugs.freedesktop.org/show_bug.cgi?id=108585
>
> Alex Deucher (6):
>   drm/amdgpu: add need_reset_on_init asic callback (v2)
>   drm/amdgpu/si: add need_reset_on_init asic callback for SI (v2)
>   drm/amdgpu/cik: add need_reset_on_init asic callback for CIK (v2)
>   drm/amdgpu/vi: add need_reset_on_init asic callback for VI (v2)
>   drm/amdgpu/soc15: add need_reset_on_init asic callback for SOC15 (v2)
>   drm/amdgpu: check if we need to reset at init time (v2)
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  3 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++
>  drivers/gpu/drm/amd/amdgpu/cik.c   | 18 ++
>  drivers/gpu/drm/amd/amdgpu/si.c|  6 ++
>  drivers/gpu/drm/amd/amdgpu/soc15.c | 20 
>  drivers/gpu/drm/amd/amdgpu/vi.c| 18 ++
>  6 files changed, 76 insertions(+)
>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 5/6] drm/amdgpu/soc15: add need_reset_on_init asic callback for SOC15 (v2)

2019-01-08 Thread Alex Deucher
SOC15 chips require a reset if the driver was previously loaded
because the PSP can only be loaded once between each reset.

v2: rebase, handle multiple asic funcs

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

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 8849b74078d6..fb01a6cda262 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -43,6 +43,7 @@
 #include "hdp/hdp_4_0_sh_mask.h"
 #include "smuio/smuio_9_0_offset.h"
 #include "smuio/smuio_9_0_sh_mask.h"
+#include "mp/mp_9_0_offset.h"
 
 #include "soc15.h"
 #include "soc15_common.h"
@@ -602,6 +603,23 @@ static bool soc15_need_full_reset(struct amdgpu_device 
*adev)
return true;
 }
 
+static bool soc15_need_reset_on_init(struct amdgpu_device *adev)
+{
+   u32 sol_reg;
+
+   if (adev->flags & AMD_IS_APU)
+   return false;
+
+   /* Check sOS sign of life register to confirm sys driver and sOS
+* are already been loaded.
+*/
+   sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
+   if (sol_reg)
+   return true;
+
+   return false;
+}
+
 static const struct amdgpu_asic_funcs soc15_asic_funcs =
 {
.read_disabled_bios = _read_disabled_bios,
@@ -617,6 +635,7 @@ static const struct amdgpu_asic_funcs soc15_asic_funcs =
.invalidate_hdp = _invalidate_hdp,
.need_full_reset = _need_full_reset,
.init_doorbell_index = _doorbell_index_init,
+   .need_reset_on_init = _need_reset_on_init,
 };
 
 static const struct amdgpu_asic_funcs vega20_asic_funcs =
@@ -634,6 +653,7 @@ static const struct amdgpu_asic_funcs vega20_asic_funcs =
.invalidate_hdp = _invalidate_hdp,
.need_full_reset = _need_full_reset,
.init_doorbell_index = _doorbell_index_init,
+   .need_reset_on_init = _need_reset_on_init,
 };
 
 static int soc15_common_early_init(void *handle)
-- 
2.20.1

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


[PATCH 6/6] drm/amdgpu: check if we need to reset at init time (v2)

2019-01-08 Thread Alex Deucher
To deal with situations like kexec or GPU VM passthrough
where the device may have been used previously without a
proper GPU reset between.

v2: rebase

bug: https://bugs.freedesktop.org/show_bug.cgi?id=108585
bug: https://bugs.freedesktop.org/show_bug.cgi?id=108754
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 1a558dc41ba6..8a61764e64cf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2550,6 +2550,17 @@ int amdgpu_device_init(struct amdgpu_device *adev,
/* detect if we are with an SRIOV vbios */
amdgpu_device_detect_sriov_bios(adev);
 
+   /* check if we need to reset the asic
+*  E.g., driver was not cleanly unloaded previously, etc.
+*/
+   if (amdgpu_asic_need_reset_on_init(adev)) {
+   r = amdgpu_asic_reset(adev);
+   if (r) {
+   dev_err(adev->dev, "asic reset on init failed\n");
+   goto failed;
+   }
+   }
+
/* Post card if necessary */
if (amdgpu_device_need_post(adev)) {
if (!adev->bios) {
-- 
2.20.1

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


[PATCH 2/6] drm/amdgpu/si: add need_reset_on_init asic callback for SI (v2)

2019-01-08 Thread Alex Deucher
SI chips don't require a reset on reload due to the nature of
the SMU on them.

v2: rebase

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

diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index f8408f88cd37..51adfe986da3 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1258,6 +1258,11 @@ static bool si_need_full_reset(struct amdgpu_device 
*adev)
return true;
 }
 
+static bool si_need_reset_on_init(struct amdgpu_device *adev)
+{
+   return false;
+}
+
 static int si_get_pcie_lanes(struct amdgpu_device *adev)
 {
u32 link_width_cntl;
@@ -1339,6 +1344,7 @@ static const struct amdgpu_asic_funcs si_asic_funcs =
.flush_hdp = _flush_hdp,
.invalidate_hdp = _invalidate_hdp,
.need_full_reset = _need_full_reset,
+   .need_reset_on_init = _need_reset_on_init,
 };
 
 static uint32_t si_get_rev_id(struct amdgpu_device *adev)
-- 
2.20.1

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


[PATCH 1/6] drm/amdgpu: add need_reset_on_init asic callback (v2)

2019-01-08 Thread Alex Deucher
Used to determine if we need to reset the asic on init due
to the driver having been previously loaded or not shutdown
cleanly.  E.g., kexec or VM passthrough.

v2: rebase

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

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index bcef6ea4bcf9..d27fa2ffb2f0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -542,6 +542,8 @@ struct amdgpu_asic_funcs {
bool (*need_full_reset)(struct amdgpu_device *adev);
/* initialize doorbell layout for specific asic*/
void (*init_doorbell_index)(struct amdgpu_device *adev);
+   /* do we need to reset the asic at init time (e.g., kexec) */
+   bool (*need_reset_on_init)(struct amdgpu_device *adev);
 };
 
 /*
@@ -1042,6 +1044,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 #define amdgpu_asic_invalidate_hdp(adev, r) 
(adev)->asic_funcs->invalidate_hdp((adev), (r))
 #define amdgpu_asic_need_full_reset(adev) 
(adev)->asic_funcs->need_full_reset((adev))
 #define amdgpu_asic_init_doorbell_index(adev) 
(adev)->asic_funcs->init_doorbell_index((adev))
+#define amdgpu_asic_need_reset_on_init(adev) 
(adev)->asic_funcs->need_reset_on_init((adev))
 
 /* Common functions */
 bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
-- 
2.20.1

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


[PATCH 0/6] kexec fixes

2019-01-08 Thread Alex Deucher
Fixes for kexec.  The GPU needs to be reset before the driver
can be loaded again reliably.  Needed for kexec for booting some
ppc platforms.  See:
https://bugs.freedesktop.org/show_bug.cgi?id=108585

Alex Deucher (6):
  drm/amdgpu: add need_reset_on_init asic callback (v2)
  drm/amdgpu/si: add need_reset_on_init asic callback for SI (v2)
  drm/amdgpu/cik: add need_reset_on_init asic callback for CIK (v2)
  drm/amdgpu/vi: add need_reset_on_init asic callback for VI (v2)
  drm/amdgpu/soc15: add need_reset_on_init asic callback for SOC15 (v2)
  drm/amdgpu: check if we need to reset at init time (v2)

 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  3 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++
 drivers/gpu/drm/amd/amdgpu/cik.c   | 18 ++
 drivers/gpu/drm/amd/amdgpu/si.c|  6 ++
 drivers/gpu/drm/amd/amdgpu/soc15.c | 20 
 drivers/gpu/drm/amd/amdgpu/vi.c| 18 ++
 6 files changed, 76 insertions(+)

-- 
2.20.1

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


[PATCH 3/6] drm/amdgpu/cik: add need_reset_on_init asic callback for CIK (v2)

2019-01-08 Thread Alex Deucher
CIK chips require a reset if the driver was previously loaded
because the SMU can only be loaded once between each reset.

v2: rebase

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

diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 71c50d8900e3..09dfaff63502 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1741,6 +1741,23 @@ static bool cik_need_full_reset(struct amdgpu_device 
*adev)
return true;
 }
 
+static bool cik_need_reset_on_init(struct amdgpu_device *adev)
+{
+   u32 clock_cntl, pc;
+
+   if (adev->flags & AMD_IS_APU)
+   return false;
+
+   /* check if the SMC is already running */
+   clock_cntl = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
+   pc = RREG32_SMC(ixSMC_PC_C);
+   if ((0 == REG_GET_FIELD(clock_cntl, SMC_SYSCON_CLOCK_CNTL_0, 
ck_disable)) &&
+   (0x20100 <= pc))
+   return true;
+
+   return false;
+}
+
 static const struct amdgpu_asic_funcs cik_asic_funcs =
 {
.read_disabled_bios = _read_disabled_bios,
@@ -1756,6 +1773,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
.invalidate_hdp = _invalidate_hdp,
.need_full_reset = _need_full_reset,
.init_doorbell_index = _doorbell_index_init,
+   .need_reset_on_init = _need_reset_on_init,
 };
 
 static int cik_common_early_init(void *handle)
-- 
2.20.1

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


[PATCH 4/6] drm/amdgpu/vi: add need_reset_on_init asic callback for VI (v2)

2019-01-08 Thread Alex Deucher
VI chips require a reset if the driver was previously loaded
because the SMU can only be loaded once between each reset.

v2: rebase

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

diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 03e7be595a0d..60ce2c1dac5c 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -941,6 +941,23 @@ static bool vi_need_full_reset(struct amdgpu_device *adev)
}
 }
 
+static bool vi_need_reset_on_init(struct amdgpu_device *adev)
+{
+   u32 clock_cntl, pc;
+
+   if (adev->flags & AMD_IS_APU)
+   return false;
+
+   /* check if the SMC is already running */
+   clock_cntl = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
+   pc = RREG32_SMC(ixSMC_PC_C);
+   if ((0 == REG_GET_FIELD(clock_cntl, SMC_SYSCON_CLOCK_CNTL_0, 
ck_disable)) &&
+   (0x20100 <= pc))
+   return true;
+
+   return false;
+}
+
 static const struct amdgpu_asic_funcs vi_asic_funcs =
 {
.read_disabled_bios = _read_disabled_bios,
@@ -956,6 +973,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
.invalidate_hdp = _invalidate_hdp,
.need_full_reset = _need_full_reset,
.init_doorbell_index = _doorbell_index_init,
+   .need_reset_on_init = _need_reset_on_init,
 };
 
 #define CZ_REV_BRISTOL(rev) \
-- 
2.20.1

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


RE: [PATCH] drm/amdgpu: expose sclk and mclk via hwmon

2019-01-08 Thread Freehill, Chris
Ditto...except if those files Felix mentioned were to go away as 
pp_od_clk_voltage more widely used, then we would need this.

I think Alex had mentioned there was some redundancy between those, but 
pp_od_clk_voltage didn't indicate the current frequencies.

Chris



-Original Message-
From: Kuehling, Felix  
Sent: Tuesday, January 8, 2019 3:44 PM
To: Deucher, Alexander ; Alex Deucher 
; amd-gfx@lists.freedesktop.org; Russell, Kent 
; Freehill, Chris 
Subject: Re: [PATCH] drm/amdgpu: expose sclk and mclk via hwmon

I'm not saying it's useless. But rocm-smi can already get the clocks from sysfs 
(pp_dpm_sclk and pp_dpm_mclk). Are these clocks any different?


Regards,
  Felix


On 2019-01-08 4:32 p.m., Deucher, Alexander wrote:
>
> Ping?  Useful for rocm-smi?
>
> --
> --
> *From:* Alex Deucher 
> *Sent:* Monday, December 10, 2018 4:17:27 PM
> *To:* amd-gfx@lists.freedesktop.org
> *Cc:* Deucher, Alexander
> *Subject:* [PATCH] drm/amdgpu: expose sclk and mclk via hwmon
>  
> Expose sclk (gfx clock) and mclk (memory clock) via hwmon compatible 
> interface.  hwmon does not actually formally specify a frequency type 
> attribute, but these are compatible with the format of the other 
> attributes exposed via hwmon.  Units are hertz.
>
> freq1_input - GPU gfx/compute clock in hertz freq2_input - GPU memory 
> clock in hertz (dGPU only)
>
> Signed-off-by: Alex Deucher 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 93
> ++
>  1 file changed, 93 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 1f61ed95727c..6d52428fc45b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -1516,6 +1516,75 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>  return count;
>  }
>  
> +static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
> + struct device_attribute *attr,
> + char *buf) {
> +   struct amdgpu_device *adev = dev_get_drvdata(dev);
> +   struct drm_device *ddev = adev->ddev;
> +   uint32_t sclk;
> +   int r, size = sizeof(sclk);
> +
> +   /* Can't get voltage when the card is off */
> +   if  ((adev->flags & AMD_IS_PX) &&
> +    (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> +   return -EINVAL;
> +
> +   /* sanity check PP is enabled */
> +   if (!(adev->powerplay.pp_funcs &&
> + adev->powerplay.pp_funcs->read_sensor))
> + return -EINVAL;
> +
> +   /* get the sclk */
> +   r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK,
> +  (void *), );
> +   if (r)
> +   return r;
> +
> +   return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000); }
> +
> +static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev,
> +   struct device_attribute 
> +*attr,
> +   char *buf) {
> +   return snprintf(buf, PAGE_SIZE, "sclk\n"); }
> +
> +static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
> + struct device_attribute *attr,
> + char *buf) {
> +   struct amdgpu_device *adev = dev_get_drvdata(dev);
> +   struct drm_device *ddev = adev->ddev;
> +   uint32_t mclk;
> +   int r, size = sizeof(mclk);
> +
> +   /* Can't get voltage when the card is off */
> +   if  ((adev->flags & AMD_IS_PX) &&
> +    (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> +   return -EINVAL;
> +
> +   /* sanity check PP is enabled */
> +   if (!(adev->powerplay.pp_funcs &&
> + adev->powerplay.pp_funcs->read_sensor))
> + return -EINVAL;
> +
> +   /* get the sclk */
> +   r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK,
> +  (void *), );
> +   if (r)
> +   return r;
> +
> +   return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000); }
> +
> +static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev,
> +   struct device_attribute 
> +*attr,
> +   char *buf) {
> +   return snprintf(buf, PAGE_SIZE, "mclk\n"); }
>  
>  /**
>   * DOC: hwmon
> @@ -1532,6 +1601,10 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   *
>   * - GPU fan
>   *
> + * - GPU gfx/compute engine clock
> + *
> + * - GPU memory clock (dGPU only)
> + *
>   * hwmon interfaces for GPU temperature:
>   *
>   * - temp1_input: the on die GPU temperature in millidegrees Celsius 
> @@ -1576,6 +1649,12 @@ static ssize_t 
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   *
>   * - fan[1-*]_enable: Enable or 

Re: [PATCH] drm/amdgpu: expose sclk and mclk via hwmon

2019-01-08 Thread Kuehling, Felix
I'm not saying it's useless. But rocm-smi can already get the clocks
from sysfs (pp_dpm_sclk and pp_dpm_mclk). Are these clocks any different?


Regards,
  Felix


On 2019-01-08 4:32 p.m., Deucher, Alexander wrote:
>
> Ping?  Useful for rocm-smi?
>
> 
> *From:* Alex Deucher 
> *Sent:* Monday, December 10, 2018 4:17:27 PM
> *To:* amd-gfx@lists.freedesktop.org
> *Cc:* Deucher, Alexander
> *Subject:* [PATCH] drm/amdgpu: expose sclk and mclk via hwmon
>  
> Expose sclk (gfx clock) and mclk (memory clock) via
> hwmon compatible interface.  hwmon does not actually
> formally specify a frequency type attribute, but these
> are compatible with the format of the other attributes
> exposed via hwmon.  Units are hertz.
>
> freq1_input - GPU gfx/compute clock in hertz
> freq2_input - GPU memory clock in hertz (dGPU only)
>
> Signed-off-by: Alex Deucher 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 93
> ++
>  1 file changed, 93 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 1f61ed95727c..6d52428fc45b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -1516,6 +1516,75 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>  return count;
>  }
>  
> +static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> +   struct amdgpu_device *adev = dev_get_drvdata(dev);
> +   struct drm_device *ddev = adev->ddev;
> +   uint32_t sclk;
> +   int r, size = sizeof(sclk);
> +
> +   /* Can't get voltage when the card is off */
> +   if  ((adev->flags & AMD_IS_PX) &&
> +    (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> +   return -EINVAL;
> +
> +   /* sanity check PP is enabled */
> +   if (!(adev->powerplay.pp_funcs &&
> + adev->powerplay.pp_funcs->read_sensor))
> + return -EINVAL;
> +
> +   /* get the sclk */
> +   r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK,
> +  (void *), );
> +   if (r)
> +   return r;
> +
> +   return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000);
> +}
> +
> +static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev,
> +   struct device_attribute *attr,
> +   char *buf)
> +{
> +   return snprintf(buf, PAGE_SIZE, "sclk\n");
> +}
> +
> +static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> +   struct amdgpu_device *adev = dev_get_drvdata(dev);
> +   struct drm_device *ddev = adev->ddev;
> +   uint32_t mclk;
> +   int r, size = sizeof(mclk);
> +
> +   /* Can't get voltage when the card is off */
> +   if  ((adev->flags & AMD_IS_PX) &&
> +    (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> +   return -EINVAL;
> +
> +   /* sanity check PP is enabled */
> +   if (!(adev->powerplay.pp_funcs &&
> + adev->powerplay.pp_funcs->read_sensor))
> + return -EINVAL;
> +
> +   /* get the sclk */
> +   r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK,
> +  (void *), );
> +   if (r)
> +   return r;
> +
> +   return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000);
> +}
> +
> +static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev,
> +   struct device_attribute *attr,
> +   char *buf)
> +{
> +   return snprintf(buf, PAGE_SIZE, "mclk\n");
> +}
>  
>  /**
>   * DOC: hwmon
> @@ -1532,6 +1601,10 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   *
>   * - GPU fan
>   *
> + * - GPU gfx/compute engine clock
> + *
> + * - GPU memory clock (dGPU only)
> + *
>   * hwmon interfaces for GPU temperature:
>   *
>   * - temp1_input: the on die GPU temperature in millidegrees Celsius
> @@ -1576,6 +1649,12 @@ static ssize_t
> amdgpu_hwmon_set_power_cap(struct device *dev,
>   *
>   * - fan[1-*]_enable: Enable or disable the sensors.1: Enable 0: Disable
>   *
> + * hwmon interfaces for GPU clocks:
> + *
> + * - freq1_input: the gfx/compute clock in hertz
> + *
> + * - freq2_input: the memory clock in hertz
> + *
>   * You can use hwmon tools like sensors to view this information on
> your system.
>   *
>   */
> @@ -1600,6 +1679,10 @@ static SENSOR_DEVICE_ATTR(power1_average,
> S_IRUGO, amdgpu_hwmon_show_power_avg,
>  static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO,
> amdgpu_hwmon_show_power_cap_max, NULL, 0);
>  static 

Re: [PATCH] drm/amdgpu: expose sclk and mclk via hwmon

2019-01-08 Thread Deucher, Alexander
Ping?  Useful for rocm-smi?


From: Alex Deucher 
Sent: Monday, December 10, 2018 4:17:27 PM
To: amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander
Subject: [PATCH] drm/amdgpu: expose sclk and mclk via hwmon

Expose sclk (gfx clock) and mclk (memory clock) via
hwmon compatible interface.  hwmon does not actually
formally specify a frequency type attribute, but these
are compatible with the format of the other attributes
exposed via hwmon.  Units are hertz.

freq1_input - GPU gfx/compute clock in hertz
freq2_input - GPU memory clock in hertz (dGPU only)

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

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 1f61ed95727c..6d52428fc45b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1516,6 +1516,75 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device 
*dev,
 return count;
 }

+static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+   struct amdgpu_device *adev = dev_get_drvdata(dev);
+   struct drm_device *ddev = adev->ddev;
+   uint32_t sclk;
+   int r, size = sizeof(sclk);
+
+   /* Can't get voltage when the card is off */
+   if  ((adev->flags & AMD_IS_PX) &&
+(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
+   return -EINVAL;
+
+   /* sanity check PP is enabled */
+   if (!(adev->powerplay.pp_funcs &&
+ adev->powerplay.pp_funcs->read_sensor))
+ return -EINVAL;
+
+   /* get the sclk */
+   r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK,
+  (void *), );
+   if (r)
+   return r;
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000);
+}
+
+static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   return snprintf(buf, PAGE_SIZE, "sclk\n");
+}
+
+static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+   struct amdgpu_device *adev = dev_get_drvdata(dev);
+   struct drm_device *ddev = adev->ddev;
+   uint32_t mclk;
+   int r, size = sizeof(mclk);
+
+   /* Can't get voltage when the card is off */
+   if  ((adev->flags & AMD_IS_PX) &&
+(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
+   return -EINVAL;
+
+   /* sanity check PP is enabled */
+   if (!(adev->powerplay.pp_funcs &&
+ adev->powerplay.pp_funcs->read_sensor))
+ return -EINVAL;
+
+   /* get the sclk */
+   r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK,
+  (void *), );
+   if (r)
+   return r;
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000);
+}
+
+static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   return snprintf(buf, PAGE_SIZE, "mclk\n");
+}

 /**
  * DOC: hwmon
@@ -1532,6 +1601,10 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device 
*dev,
  *
  * - GPU fan
  *
+ * - GPU gfx/compute engine clock
+ *
+ * - GPU memory clock (dGPU only)
+ *
  * hwmon interfaces for GPU temperature:
  *
  * - temp1_input: the on die GPU temperature in millidegrees Celsius
@@ -1576,6 +1649,12 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device 
*dev,
  *
  * - fan[1-*]_enable: Enable or disable the sensors.1: Enable 0: Disable
  *
+ * hwmon interfaces for GPU clocks:
+ *
+ * - freq1_input: the gfx/compute clock in hertz
+ *
+ * - freq2_input: the memory clock in hertz
+ *
  * You can use hwmon tools like sensors to view this information on your 
system.
  *
  */
@@ -1600,6 +1679,10 @@ static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, 
amdgpu_hwmon_show_power_avg,
 static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, 
amdgpu_hwmon_show_power_cap_max, NULL, 0);
 static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, 
amdgpu_hwmon_show_power_cap_min, NULL, 0);
 static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, 
amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0);
+static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO, amdgpu_hwmon_show_sclk, NULL, 
0);
+static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO, amdgpu_hwmon_show_sclk_label, 
NULL, 0);
+static SENSOR_DEVICE_ATTR(freq2_input, S_IRUGO, amdgpu_hwmon_show_mclk, NULL, 
0);
+static SENSOR_DEVICE_ATTR(freq2_label, S_IRUGO, amdgpu_hwmon_show_mclk_label, 

Re: [PATCH v2 0/3] drm/amdgpu: Fix suspend/resume issues with MST

2019-01-08 Thread Lyude Paul
On Tue, 2019-01-08 at 16:17 -0500, Alex Deucher wrote:
> On Tue, Jan 8, 2019 at 4:11 PM Lyude Paul  wrote:
> > Fix the suspend/issues that Jerry Zuo found in amdgpu, and add some
> > compiler warnings for drivers ignoring the return code of
> > drm_dp_mst_topology_mgr_resume() to help ensure we don't need to fix
> > this again in the future for someone else's driver.
> > 
> > Cc: Jerry Zuo 
> > 
> > Lyude Paul (3):
> >   drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume()
> >   drm/amdgpu: Don't fail resume process if resuming atomic state fails
> >   drm/dp_mst: Add __must_check to drm_dp_mst_topology_mgr_resume()
> 
> I can take these through the amdgpu tree or you can commit them to
> drm-misc (assuming you have commit rights).  Either way works for me.
I don't mind just pushing these to drm-misc since you seem OK with it. Thanks!
> 
> Thanks,
> 
> Alex
> 
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 37 +--
> >  include/drm/drm_dp_mst_helper.h   |  3 +-
> >  2 files changed, 27 insertions(+), 13 deletions(-)
> > 
> > --
> > 2.20.1
> > 
> > ___
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/amd-gfx
-- 
Cheers,
Lyude Paul

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


Re: [PATCH v2 0/3] drm/amdgpu: Fix suspend/resume issues with MST

2019-01-08 Thread Alex Deucher
On Tue, Jan 8, 2019 at 4:11 PM Lyude Paul  wrote:
>
> Fix the suspend/issues that Jerry Zuo found in amdgpu, and add some
> compiler warnings for drivers ignoring the return code of
> drm_dp_mst_topology_mgr_resume() to help ensure we don't need to fix
> this again in the future for someone else's driver.
>
> Cc: Jerry Zuo 
>
> Lyude Paul (3):
>   drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume()
>   drm/amdgpu: Don't fail resume process if resuming atomic state fails
>   drm/dp_mst: Add __must_check to drm_dp_mst_topology_mgr_resume()

I can take these through the amdgpu tree or you can commit them to
drm-misc (assuming you have commit rights).  Either way works for me.

Thanks,

Alex

>
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 37 +--
>  include/drm/drm_dp_mst_helper.h   |  3 +-
>  2 files changed, 27 insertions(+), 13 deletions(-)
>
> --
> 2.20.1
>
> ___
> 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


[PATCH v2 3/3] drm/dp_mst: Add __must_check to drm_dp_mst_topology_mgr_resume()

2019-01-08 Thread Lyude Paul
Since I've had to fix two cases of drivers not checking the return code
from this function, let's make the compiler complain so this doesn't
come up again in the future.

Changes since v1:
* Remove unneeded __must_check in function declaration - danvet

Signed-off-by: Lyude Paul 
Cc: Jerry Zuo 
Reviewed-by: Daniel Vetter 
Reviewed-by: Harry Wentland 
---
 include/drm/drm_dp_mst_helper.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 371cc2816477..4355b55d0081 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -614,7 +614,8 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
  struct drm_dp_mst_topology_mgr *mgr);
 
 void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
-int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
+int __must_check
+drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
 struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct 
drm_atomic_state *state,
struct 
drm_dp_mst_topology_mgr *mgr);
 int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
-- 
2.20.1

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


[PATCH v2 2/3] drm/amdgpu: Don't fail resume process if resuming atomic state fails

2019-01-08 Thread Lyude Paul
This is an ugly one unfortunately. Currently, all DRM drivers supporting
atomic modesetting will save the state that userspace had set before
suspending, then attempt to restore that state on resume. This probably
worked very well at one point, like many other things, until DP MST came
into the picture. While it's easy to restore state on normal display
connectors that were disconnected during suspend regardless of their
state post-resume, this can't really be done with MST because of the
fact that setting up a downstream sink requires performing sideband
transactions between the source and the MST hub, sending out the ACT
packets, etc.

Because of this, there isn't really a guarantee that we can restore the
atomic state we had before suspend once we've resumed. This sucks pretty
bad, but so far I haven't run into any compositors that this actually
causes serious issues with. Most compositors will notice the hotplug we
send afterwards, and then reprobe state.

Since nouveau and i915 also don't fail the suspend/resume process due to
failing to restore the atomic state, let's make amdgpu match this
behavior. Better to resume the GPU properly, then to stop the process
half way because of a potentially unavoidable atomic commit failure.

Eventually, we'll have a real fix for this problem on the DRM level. But
we've got some more important low-hanging fruit to deal with first.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Jerry Zuo 
Cc:  # v4.15+
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++---
 1 file changed, 2 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 3f326a2c513b..a3e65e457348 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -912,7 +912,6 @@ static int dm_resume(void *handle)
struct drm_plane_state *new_plane_state;
struct dm_plane_state *dm_new_plane_state;
enum dc_connection_type new_connection_type = dc_connection_none;
-   int ret;
int i;
 
/* power on hardware */
@@ -985,13 +984,13 @@ static int dm_resume(void *handle)
}
}
 
-   ret = drm_atomic_helper_resume(ddev, dm->cached_state);
+   drm_atomic_helper_resume(ddev, dm->cached_state);
 
dm->cached_state = NULL;
 
amdgpu_dm_irq_resume_late(adev);
 
-   return ret;
+   return 0;
 }
 
 /**
-- 
2.20.1

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


[PATCH v2 1/3] drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume()

2019-01-08 Thread Lyude Paul
drm_dp_mst_topology_mgr_resume() returns whether or not it managed to
find the topology in question after a suspend resume cycle, and the
driver is supposed to check this value and disable MST accordingly if
it's gone-in addition to sending a hotplug in order to notify userspace
that something changed during suspend.

Currently, amdgpu just makes the mistake of ignoring the return code
from drm_dp_mst_topology_mgr_resume() which means that if a topology was
removed in suspend, amdgpu never notices and assumes it's still
connected which leads to all sorts of problems.

So, fix this by actually checking the rc from
drm_dp_mst_topology_mgr_resume(). Also, reformat the rest of the
function while we're at it to fix the over-indenting.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Jerry Zuo 
Cc:  # v4.15+
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 32 +--
 1 file changed, 23 insertions(+), 9 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 8a626d16e8e3..3f326a2c513b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -699,22 +699,36 @@ static void s3_handle_mst(struct drm_device *dev, bool 
suspend)
 {
struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector;
+   struct drm_dp_mst_topology_mgr *mgr;
+   int ret;
+   bool need_hotplug = false;
 
drm_modeset_lock(>mode_config.connection_mutex, NULL);
 
-   list_for_each_entry(connector, >mode_config.connector_list, head) {
-  aconnector = to_amdgpu_dm_connector(connector);
-  if (aconnector->dc_link->type == dc_connection_mst_branch &&
-  !aconnector->mst_port) {
+   list_for_each_entry(connector, >mode_config.connector_list,
+   head) {
+   aconnector = to_amdgpu_dm_connector(connector);
+   if (aconnector->dc_link->type != dc_connection_mst_branch ||
+   aconnector->mst_port)
+   continue;
+
+   mgr = >mst_mgr;
 
-  if (suspend)
-  
drm_dp_mst_topology_mgr_suspend(>mst_mgr);
-  else
-  
drm_dp_mst_topology_mgr_resume(>mst_mgr);
-  }
+   if (suspend) {
+   drm_dp_mst_topology_mgr_suspend(mgr);
+   } else {
+   ret = drm_dp_mst_topology_mgr_resume(mgr);
+   if (ret < 0) {
+   drm_dp_mst_topology_mgr_set_mst(mgr, false);
+   need_hotplug = true;
+   }
+   }
}
 
drm_modeset_unlock(>mode_config.connection_mutex);
+
+   if (need_hotplug)
+   drm_kms_helper_hotplug_event(dev);
 }
 
 /**
-- 
2.20.1

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


[PATCH v2 0/3] drm/amdgpu: Fix suspend/resume issues with MST

2019-01-08 Thread Lyude Paul
Fix the suspend/issues that Jerry Zuo found in amdgpu, and add some
compiler warnings for drivers ignoring the return code of
drm_dp_mst_topology_mgr_resume() to help ensure we don't need to fix
this again in the future for someone else's driver.

Cc: Jerry Zuo 

Lyude Paul (3):
  drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume()
  drm/amdgpu: Don't fail resume process if resuming atomic state fails
  drm/dp_mst: Add __must_check to drm_dp_mst_topology_mgr_resume()

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 37 +--
 include/drm/drm_dp_mst_helper.h   |  3 +-
 2 files changed, 27 insertions(+), 13 deletions(-)

-- 
2.20.1

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


Re: [PATCH v4 00/16] MST refcounting/atomic helpers cleanup

2019-01-08 Thread Lyude Paul
On Tue, 2019-01-08 at 19:57 +, Wentland, Harry wrote:
> On 2019-01-04 7:14 p.m., Lyude Paul wrote:
> > This is the series I've been working on for a while now to get all of
> > the atomic DRM drivers in the tree to use the atomic MST helpers, and to
> > make the atomic MST helpers actually idempotent. Turns out it's a lot
> > more difficult to do that without also fixing how port and branch device
> > refcounting works so that it actually makes sense, since the current
> > upstream implementation requires a ton of magic in the atomic helpers to
> > work around properly and in many situations just plain doesn't work as
> > intended.
> > 
> > There's still more cleanup that can be done, but I think this is a good
> > place to start off for now :).
> > 
> > This version just contains some changes that I forgot to make that had
> > been requested much earlier, mainly in regards to the atomic checking
> > code I added to i915 and nouveau (but not the helpers).
> > 
> > Also, per-request I've made a gitlab branch available for this:
> > 
> > https://gitlab.freedesktop.org/lyudess/linux/commits/wip/mst-dual-kref-start-v4
> > 
> > Lyude Paul (16):
> >   drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and
> > friends
> >   drm/dp_mst: Introduce new refcounting scheme for mstbs and ports
> >   drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref
> > fails
> >   drm/dp_mst: Stop releasing VCPI when removing ports from topology
> >   drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs
> >   drm/i915: Keep malloc references to MST ports
> >   drm/amdgpu/display: Keep malloc ref to MST port
> >   drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()
> >   drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()
> >   drm/nouveau: Keep malloc references to MST ports
> >   drm/nouveau: Stop unsetting mstc->port, use malloc refs
> >   drm/nouveau: Grab payload lock in nv50_msto_payload()
> >   drm/dp_mst: Add some atomic state iterator macros
> >   drm/dp_mst: Start tracking per-port VCPI allocations
> >   drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()
> >   drm/nouveau: Use atomic VCPI helpers for MST
> > 
> 
> Somehow I left my RB on v2 for a while. Either way patches 2-5, and 7 are
> Reviewed-by: Harry Wentland 
> 
> Haven't had a chance to take a look at 13-15 but noticed the "Changes since
> v" mention versions that either aren't on the mailing list or don't line up
> with the patch versioning.
That's intentional! Those were patches that were part of a different series
that got replaced by this one, so the older versions are from the previous
series
> 
> Harry 
> 
> >  .../gpu/dp-mst/topology-figure-1.dot  |  52 +
> >  .../gpu/dp-mst/topology-figure-2.dot  |  56 ++
> >  .../gpu/dp-mst/topology-figure-3.dot  |  59 ++
> >  Documentation/gpu/drm-kms-helpers.rst |  26 +-
> >  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  11 +-
> >  drivers/gpu/drm/drm_dp_mst_topology.c | 938 ++
> >  drivers/gpu/drm/i915/intel_connector.c|   4 +
> >  drivers/gpu/drm/i915/intel_display.c  |   4 +
> >  drivers/gpu/drm/i915/intel_dp_mst.c   |  55 +-
> >  drivers/gpu/drm/nouveau/dispnv50/disp.c   |  96 +-
> >  include/drm/drm_dp_mst_helper.h   | 151 ++-
> >  11 files changed, 1203 insertions(+), 249 deletions(-)
> >  create mode 100644 Documentation/gpu/dp-mst/topology-figure-1.dot
> >  create mode 100644 Documentation/gpu/dp-mst/topology-figure-2.dot
> >  create mode 100644 Documentation/gpu/dp-mst/topology-figure-3.dot
> > 
-- 
Cheers,
Lyude Paul

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


Re: [PATCH v4 00/16] MST refcounting/atomic helpers cleanup

2019-01-08 Thread Wentland, Harry
On 2019-01-04 7:14 p.m., Lyude Paul wrote:
> This is the series I've been working on for a while now to get all of
> the atomic DRM drivers in the tree to use the atomic MST helpers, and to
> make the atomic MST helpers actually idempotent. Turns out it's a lot
> more difficult to do that without also fixing how port and branch device
> refcounting works so that it actually makes sense, since the current
> upstream implementation requires a ton of magic in the atomic helpers to
> work around properly and in many situations just plain doesn't work as
> intended.
> 
> There's still more cleanup that can be done, but I think this is a good
> place to start off for now :).
> 
> This version just contains some changes that I forgot to make that had
> been requested much earlier, mainly in regards to the atomic checking
> code I added to i915 and nouveau (but not the helpers).
> 
> Also, per-request I've made a gitlab branch available for this:
> 
> https://gitlab.freedesktop.org/lyudess/linux/commits/wip/mst-dual-kref-start-v4
> 
> Lyude Paul (16):
>   drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and
> friends
>   drm/dp_mst: Introduce new refcounting scheme for mstbs and ports
>   drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref
> fails
>   drm/dp_mst: Stop releasing VCPI when removing ports from topology
>   drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs
>   drm/i915: Keep malloc references to MST ports
>   drm/amdgpu/display: Keep malloc ref to MST port
>   drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()
>   drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()
>   drm/nouveau: Keep malloc references to MST ports
>   drm/nouveau: Stop unsetting mstc->port, use malloc refs
>   drm/nouveau: Grab payload lock in nv50_msto_payload()
>   drm/dp_mst: Add some atomic state iterator macros
>   drm/dp_mst: Start tracking per-port VCPI allocations
>   drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()
>   drm/nouveau: Use atomic VCPI helpers for MST
> 

Somehow I left my RB on v2 for a while. Either way patches 2-5, and 7 are
Reviewed-by: Harry Wentland 

Haven't had a chance to take a look at 13-15 but noticed the "Changes since v" 
mention versions that either aren't on the mailing list or don't line up with 
the patch versioning.

Harry 

>  .../gpu/dp-mst/topology-figure-1.dot  |  52 +
>  .../gpu/dp-mst/topology-figure-2.dot  |  56 ++
>  .../gpu/dp-mst/topology-figure-3.dot  |  59 ++
>  Documentation/gpu/drm-kms-helpers.rst |  26 +-
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  11 +-
>  drivers/gpu/drm/drm_dp_mst_topology.c | 938 ++
>  drivers/gpu/drm/i915/intel_connector.c|   4 +
>  drivers/gpu/drm/i915/intel_display.c  |   4 +
>  drivers/gpu/drm/i915/intel_dp_mst.c   |  55 +-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c   |  96 +-
>  include/drm/drm_dp_mst_helper.h   | 151 ++-
>  11 files changed, 1203 insertions(+), 249 deletions(-)
>  create mode 100644 Documentation/gpu/dp-mst/topology-figure-1.dot
>  create mode 100644 Documentation/gpu/dp-mst/topology-figure-2.dot
>  create mode 100644 Documentation/gpu/dp-mst/topology-figure-3.dot
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH v2 07/16] drm/amdgpu/display: Keep malloc ref to MST port

2019-01-08 Thread Wentland, Harry
On 2018-12-19 7:19 p.m., Lyude Paul wrote:
> Just like i915 and nouveau, it's a good idea for us to hold a malloc
> reference to the port here so that we never pass a freed pointer to any
> of the DP MST helper functions.
> 
> Also, we stop unsetting aconnector->port in
> dm_dp_destroy_mst_connector(). There's literally no point to that
> assignment that I can see anyway.
> 
> Signed-off-by: Lyude Paul 
> Cc: Daniel Vetter 
> Cc: David Airlie 
> Cc: Jerry Zuo 
> Cc: Harry Wentland 
> Cc: Juston Li 

Reviewed-by: Harry Wentland 

Harry


> ---
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 11 +++
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 5e7ca1f3a8d1..24632727e127 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -191,6 +191,7 @@ dm_dp_mst_connector_destroy(struct drm_connector 
> *connector)
>   drm_encoder_cleanup(_encoder->base);
>   kfree(amdgpu_encoder);
>   drm_connector_cleanup(connector);
> + drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
>   kfree(amdgpu_dm_connector);
>  }
>  
> @@ -363,7 +364,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr 
> *mgr,
>   amdgpu_dm_connector_funcs_reset(connector);
>  
>   DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
> - aconnector, connector->base.id, aconnector->mst_port);
> +  aconnector, connector->base.id, aconnector->mst_port);
> +
> + drm_dp_mst_get_port_malloc(port);
>  
>   DRM_DEBUG_KMS(":%d\n", connector->base.id);
>  
> @@ -379,12 +382,12 @@ static void dm_dp_destroy_mst_connector(struct 
> drm_dp_mst_topology_mgr *mgr,
>   struct amdgpu_dm_connector *aconnector = 
> to_amdgpu_dm_connector(connector);
>  
>   DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
> - aconnector, connector->base.id, 
> aconnector->mst_port);
> +  aconnector, connector->base.id, aconnector->mst_port);
>  
> - aconnector->port = NULL;
>   if (aconnector->dc_sink) {
>   amdgpu_dm_update_freesync_caps(connector, NULL);
> - dc_link_remove_remote_sink(aconnector->dc_link, 
> aconnector->dc_sink);
> + dc_link_remove_remote_sink(aconnector->dc_link,
> +aconnector->dc_sink);
>   dc_sink_release(aconnector->dc_sink);
>   aconnector->dc_sink = NULL;
>   }
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH AUTOSEL 4.4 07/28] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit 520f08df45fbe300ed650da786a74093d658b7e1 ]

When variable refresh rate is active the hardware counter can return
a position >= vtotal. This results in a vpos being returned from
amdgpu_display_get_crtc_scanoutpos that's a positive value. The
positive value indicates to the caller that the display is
currently in scanout when the display is actually still in vblank.

This is because the vfront porch duration is unknown with variable
refresh active and will end when either a page flip occurs or the
timeout specified by the driver/display is reached.

The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
same when the position is below vtotal. When the position is above
vtotal the function will return a value that is effectively -vbl_end,
the size of the vback porch.

The only caller affected by this change is the DRM helper for
calculating vblank timestamps. This change corrects behavior for
calculating the page flip timestamp from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index c555781685ea..0947567900bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -883,7 +883,12 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, 
unsigned int pipe,
/* Inside "upper part" of vblank area? Apply corrective offset if so: */
if (in_vbl && (*vpos >= vbl_start)) {
vtotal = mode->crtc_vtotal;
-   *vpos = *vpos - vtotal;
+
+   /* With variable refresh rate displays the vpos can exceed
+* the vtotal value. Clamp to 0 to return -vbl_end instead
+* of guessing the remaining number of lines until scanout.
+*/
+   *vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
}
 
/* Correct for shifted end of vbl at vbl_end. */
-- 
2.19.1

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


[PATCH AUTOSEL 4.9 10/36] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit 520f08df45fbe300ed650da786a74093d658b7e1 ]

When variable refresh rate is active the hardware counter can return
a position >= vtotal. This results in a vpos being returned from
amdgpu_display_get_crtc_scanoutpos that's a positive value. The
positive value indicates to the caller that the display is
currently in scanout when the display is actually still in vblank.

This is because the vfront porch duration is unknown with variable
refresh active and will end when either a page flip occurs or the
timeout specified by the driver/display is reached.

The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
same when the position is below vtotal. When the position is above
vtotal the function will return a value that is effectively -vbl_end,
the size of the vback porch.

The only caller affected by this change is the DRM helper for
calculating vblank timestamps. This change corrects behavior for
calculating the page flip timestamp from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 15a2d8f3725d..5042ae072386 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -856,7 +856,12 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, 
unsigned int pipe,
/* Inside "upper part" of vblank area? Apply corrective offset if so: */
if (in_vbl && (*vpos >= vbl_start)) {
vtotal = mode->crtc_vtotal;
-   *vpos = *vpos - vtotal;
+
+   /* With variable refresh rate displays the vpos can exceed
+* the vtotal value. Clamp to 0 to return -vbl_end instead
+* of guessing the remaining number of lines until scanout.
+*/
+   *vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
}
 
/* Correct for shifted end of vbl at vbl_end. */
-- 
2.19.1

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


[PATCH AUTOSEL 4.14 13/53] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit 520f08df45fbe300ed650da786a74093d658b7e1 ]

When variable refresh rate is active the hardware counter can return
a position >= vtotal. This results in a vpos being returned from
amdgpu_display_get_crtc_scanoutpos that's a positive value. The
positive value indicates to the caller that the display is
currently in scanout when the display is actually still in vblank.

This is because the vfront porch duration is unknown with variable
refresh active and will end when either a page flip occurs or the
timeout specified by the driver/display is reached.

The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
same when the position is below vtotal. When the position is above
vtotal the function will return a value that is effectively -vbl_end,
the size of the vback porch.

The only caller affected by this change is the DRM helper for
calculating vblank timestamps. This change corrects behavior for
calculating the page flip timestamp from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 6ad243293a78..8c0a208e43c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -855,7 +855,12 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, 
unsigned int pipe,
/* Inside "upper part" of vblank area? Apply corrective offset if so: */
if (in_vbl && (*vpos >= vbl_start)) {
vtotal = mode->crtc_vtotal;
-   *vpos = *vpos - vtotal;
+
+   /* With variable refresh rate displays the vpos can exceed
+* the vtotal value. Clamp to 0 to return -vbl_end instead
+* of guessing the remaining number of lines until scanout.
+*/
+   *vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
}
 
/* Correct for shifted end of vbl at vbl_end. */
-- 
2.19.1

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


[PATCH AUTOSEL 4.19 30/97] drm/amdgpu: Reorder uvd ring init before uvd resume

2019-01-08 Thread Sasha Levin
From: Chris Wilson 

[ Upstream commit 3b34c14fd50c302db091f020f26dd00ede902c80 ]

As amd_uvd_resume() accesses the uvd ring, it must be initialised first
or else we trigger errors like:

[5.595963] [drm] Found UVD firmware Version: 1.87 Family ID: 17
[5.595969] [drm] PSP loading UVD firmware
[5.596266] [ cut here ]
[5.596268] ODEBUG: assert_init not available (active state 0) object type: 
timer_list hint:   (null)
[5.596285] WARNING: CPU: 0 PID: 507 at lib/debugobjects.c:329 
debug_print_object+0x6a/0x80
[5.596286] Modules linked in: amdgpu(+) hid_logitech_hidpp(+) chash 
gpu_sched amd_iommu_v2 ttm drm_kms_helper crc32c_intel drm hid_sony ff_memless 
igb hid_logitech_dj nvme dca i2c_algo_bit nvme_core wmi pinctrl_amd uas 
usb_storage
[5.596299] CPU: 0 PID: 507 Comm: systemd-udevd Tainted: GW 
4.20.0-0.rc1.git4.1.fc30.x86_64 #1
[5.596301] Hardware name: System manufacturer System Product Name/ROG STRIX 
X470-I GAMING, BIOS 0901 07/23/2018
[5.596303] RIP: 0010:debug_print_object+0x6a/0x80
[5.596305] Code: 8b 43 10 83 c2 01 8b 4b 14 4c 89 e6 89 15 e6 82 b0 02 4c 
8b 45 00 48 c7 c7 60 fd 34 a6 48 8b 14 c5 a0 da 08 a6 e8 6a 6a b8 ff <0f> 0b 5b 
83 05 d0 45 3e 01 01 5d 41 5c c3 83 05 c5 45 3e 01 01 c3
[5.596306] RSP: 0018:a02ac863f8c0 EFLAGS: 00010282
[5.596307] RAX:  RBX: a02ac863f8e0 RCX: 0006
[5.596308] RDX: 0007 RSI: 9160e9a7bfe8 RDI: 9160f91d6c60
[5.596310] RBP: a6742740 R08: 0002 R09: 
[5.596311] R10:  R11:  R12: a634ff69
[5.596312] R13: 000b79d0 R14: a80f76d8 R15: 00266000
[5.596313] FS:  7f762abf7940() GS:9160f900() 
knlGS:
[5.596314] CS:  0010 DS:  ES:  CR0: 80050033
[5.596315] CR2: 55fdc593f000 CR3: 0007e999c000 CR4: 003406f0
[5.596317] Call Trace:
[5.596321]  debug_object_assert_init+0x14a/0x180
[5.596327]  del_timer+0x2e/0x90
[5.596383]  amdgpu_fence_process+0x47/0x100 [amdgpu]
[5.596430]  amdgpu_uvd_resume+0xf6/0x120 [amdgpu]
[5.596475]  uvd_v7_0_sw_init+0xe0/0x280 [amdgpu]
[5.596523]  amdgpu_device_init.cold.30+0xf97/0x14b6 [amdgpu]
[5.596563]  ? amdgpu_driver_load_kms+0x53/0x330 [amdgpu]
[5.596604]  amdgpu_driver_load_kms+0x86/0x330 [amdgpu]
[5.596614]  drm_dev_register+0x115/0x150 [drm]
[5.596654]  amdgpu_pci_probe+0xbd/0x120 [amdgpu]
[5.596658]  local_pci_probe+0x41/0x90
[5.596661]  pci_device_probe+0x188/0x1a0
[5.59]  really_probe+0xf8/0x3b0
[5.596669]  driver_probe_device+0xb3/0xf0
[5.596672]  __driver_attach+0xe1/0x110
[5.596674]  ? driver_probe_device+0xf0/0xf0
[5.596676]  bus_for_each_dev+0x79/0xc0
[5.596679]  bus_add_driver+0x155/0x230
[5.596681]  ? 0xc07d9000
[5.596683]  driver_register+0x6b/0xb0
[5.596685]  ? 0xc07d9000
[5.596688]  do_one_initcall+0x5d/0x2be
[5.596691]  ? rcu_read_lock_sched_held+0x79/0x80
[5.596693]  ? kmem_cache_alloc_trace+0x264/0x290
[5.596695]  ? do_init_module+0x22/0x210
[5.596698]  do_init_module+0x5a/0x210
[5.596701]  load_module+0x2137/0x2430
[5.596703]  ? lockdep_hardirqs_on+0xed/0x180
[5.596714]  ? __do_sys_init_module+0x150/0x1a0
[5.596715]  __do_sys_init_module+0x150/0x1a0
[5.596722]  do_syscall_64+0x60/0x1f0
[5.596725]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[5.596726] RIP: 0033:0x7f762b877dee
[5.596728] Code: 48 8b 0d 9d 20 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 
0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 01 
f0 ff ff 73 01 c3 48 8b 0d 6a 20 0c 00 f7 d8 64 89 01 48
[5.596729] RSP: 002b:7ffc777b8558 EFLAGS: 0246 ORIG_RAX: 
00af
[5.596730] RAX: ffda RBX: 55fdc48da320 RCX: 7f762b877dee
[5.596731] RDX: 7f762b9f284d RSI: 006c5fc6 RDI: 55fdc527a060
[5.596732] RBP: 7f762b9f284d R08: 0003 R09: 0002
[5.596733] R10: 55fdc48ad010 R11: 0246 R12: 55fdc527a060
[5.596734] R13: 55fdc48dca20 R14: 0002 R15: 
[5.596740] irq event stamp: 134618
[5.596743] hardirqs last  enabled at (134617): [] 
console_unlock+0x45e/0x610
[5.596744] hardirqs last disabled at (134618): [] 
trace_hardirqs_off_thunk+0x1a/0x1c
[5.596746] softirqs last  enabled at (133146): [] 
__do_softirq+0x365/0x47c
[5.596748] softirqs last disabled at (133139): [] 
irq_exit+0x119/0x120
[5.596749] ---[ end trace eaee508abfebccdc ]---

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108709
Reviewed-by: Christian König 
Signed-off-by: Chris Wilson 
Cc: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 8 
 

[PATCH AUTOSEL 4.19 26/97] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit 520f08df45fbe300ed650da786a74093d658b7e1 ]

When variable refresh rate is active the hardware counter can return
a position >= vtotal. This results in a vpos being returned from
amdgpu_display_get_crtc_scanoutpos that's a positive value. The
positive value indicates to the caller that the display is
currently in scanout when the display is actually still in vblank.

This is because the vfront porch duration is unknown with variable
refresh active and will end when either a page flip occurs or the
timeout specified by the driver/display is reached.

The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
same when the position is below vtotal. When the position is above
vtotal the function will return a value that is effectively -vbl_end,
the size of the vback porch.

The only caller affected by this change is the DRM helper for
calculating vblank timestamps. This change corrects behavior for
calculating the page flip timestamp from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 686a26de50f9..9c940bbed608 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -857,7 +857,12 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device 
*dev,
/* Inside "upper part" of vblank area? Apply corrective offset if so: */
if (in_vbl && (*vpos >= vbl_start)) {
vtotal = mode->crtc_vtotal;
-   *vpos = *vpos - vtotal;
+
+   /* With variable refresh rate displays the vpos can exceed
+* the vtotal value. Clamp to 0 to return -vbl_end instead
+* of guessing the remaining number of lines until scanout.
+*/
+   *vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
}
 
/* Correct for shifted end of vbl at vbl_end. */
-- 
2.19.1

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


[PATCH AUTOSEL 4.19 03/97] drm/amd/display: Guard against null stream_state in set_crc_source

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit f41a895026b8cb6f765190de7d2e7bc3ccbbd183 ]

[Why]

The igt@kms_plane@pixel-format-pipe tests can create a sequence where
stream_state is NULL during amdgpu_dm_crtc_set_crc_source which results
in a null pointer dereference.

[How]

Guard against stream_state being NULL before accessing its fields. This
doesn't fix the root cause of the issue so a DRM_ERROR is generated
to still fail the tests.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: David Francis 
Acked-by: Leo Li 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 9bfb040352e9..6a6d977ddd7a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -60,6 +60,11 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, 
const char *src_name,
return -EINVAL;
}
 
+   if (!stream_state) {
+   DRM_ERROR("No stream state for CRTC%d\n", crtc->index);
+   return -EINVAL;
+   }
+
/* When enabling CRC, we should also disable dithering. */
if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) {
if (dc_stream_configure_crc(stream_state->ctx->dc,
-- 
2.19.1

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


[PATCH AUTOSEL 4.19 04/97] drm/amdkfd: fix interrupt spin lock

2019-01-08 Thread Sasha Levin
From: Christian König 

[ Upstream commit 2383a767c0ca06f96534456d8313909017c6c8d0 ]

Vega10 has multiple interrupt rings, so this can be called from multiple
calles at the same time resulting in:

[   71.779334] 
[   71.779406] WARNING: inconsistent lock state
[   71.779478] 4.19.0-rc1+ #44 Tainted: GW
[   71.779565] 
[   71.779637] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
[   71.779740] kworker/6:1/120 [HC0[0]:SC0[0]:HE1:SE1] takes:
[   71.779832] ad761971 (&(>interrupt_lock)->rlock){?...},
at: kgd2kfd_interrupt+0x75/0x100 [amdgpu]
[   71.780058] {IN-HARDIRQ-W} state was registered at:
[   71.780115]   _raw_spin_lock+0x2c/0x40
[   71.780180]   kgd2kfd_interrupt+0x75/0x100 [amdgpu]
[   71.780248]   amdgpu_irq_callback+0x6c/0x150 [amdgpu]
[   71.780315]   amdgpu_ih_process+0x88/0x100 [amdgpu]
[   71.780380]   amdgpu_irq_handler+0x20/0x40 [amdgpu]
[   71.780409]   __handle_irq_event_percpu+0x49/0x2a0
[   71.780436]   handle_irq_event_percpu+0x30/0x70
[   71.780461]   handle_irq_event+0x37/0x60
[   71.780484]   handle_edge_irq+0x83/0x1b0
[   71.780506]   handle_irq+0x1f/0x30
[   71.780526]   do_IRQ+0x53/0x110
[   71.780544]   ret_from_intr+0x0/0x22
[   71.780566]   cpuidle_enter_state+0xaa/0x330
[   71.780591]   do_idle+0x203/0x280
[   71.780610]   cpu_startup_entry+0x6f/0x80
[   71.780634]   start_secondary+0x1b0/0x200
[   71.780657]   secondary_startup_64+0xa4/0xb0

Fix this by always using irq save spin locks.

Signed-off-by: Christian König 
Acked-by: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 1427675d0e5a..5aba50f63ac6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -661,6 +661,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void 
*ih_ring_entry)
 {
uint32_t patched_ihre[KFD_MAX_RING_ENTRY_SIZE];
bool is_patched = false;
+   unsigned long flags;
 
if (!kfd->init_complete)
return;
@@ -670,7 +671,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void 
*ih_ring_entry)
return;
}
 
-   spin_lock(>interrupt_lock);
+   spin_lock_irqsave(>interrupt_lock, flags);
 
if (kfd->interrupts_active
&& interrupt_is_wanted(kfd, ih_ring_entry,
@@ -679,7 +680,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void 
*ih_ring_entry)
 is_patched ? patched_ihre : ih_ring_entry))
queue_work(kfd->ih_wq, >interrupt_work);
 
-   spin_unlock(>interrupt_lock);
+   spin_unlock_irqrestore(>interrupt_lock, flags);
 }
 
 int kgd2kfd_quiesce_mm(struct mm_struct *mm)
-- 
2.19.1

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


Re: [PATCH v2 05/16] drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs

2019-01-08 Thread Wentland, Harry
On 2018-12-19 7:19 p.m., Lyude Paul wrote:
> Up until now, freeing payloads on remote MST hubs that just had ports
> removed has almost never worked because we've been relying on port
> validation in order to stop us from accessing ports that have already
> been freed from memory, but ports which need their payloads released due
> to being removed will never be a valid part of the topology after
> they've been removed.
> 
> Since we've introduced malloc refs, we can replace all of the validation
> logic in payload helpers which are used for deallocation with some
> well-placed malloc krefs. This ensures that regardless of whether or not
> the ports are still valid and in the topology, any port which has an
> allocated payload will remain allocated in memory until it's payloads
> have been removed - finally allowing us to actually release said
> payloads correctly.
> 
> Signed-off-by: Lyude Paul 
> Reviewed-by: Daniel Vetter 
> Cc: David Airlie 
> Cc: Jerry Zuo 
> Cc: Harry Wentland 
> Cc: Juston Li 

Reviewed-by: Harry Wentland 

Harry

> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 54 +++
>  1 file changed, 30 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index ef8637f37564..11dd3ede7b7d 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -2100,10 +2100,6 @@ static int drm_dp_payload_send_msg(struct 
> drm_dp_mst_topology_mgr *mgr,
>   u8 sinks[DRM_DP_MAX_SDP_STREAMS];
>   int i;
>  
> - port = drm_dp_mst_topology_get_port_validated(mgr, port);
> - if (!port)
> - return -EINVAL;
> -
>   port_num = port->port_num;
>   mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
>   if (!mstb) {
> @@ -2111,10 +2107,8 @@ static int drm_dp_payload_send_msg(struct 
> drm_dp_mst_topology_mgr *mgr,
>  port->parent,
>  _num);
>  
> - if (!mstb) {
> - drm_dp_mst_topology_put_port(port);
> + if (!mstb)
>   return -EINVAL;
> - }
>   }
>  
>   txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> @@ -2151,7 +2145,6 @@ static int drm_dp_payload_send_msg(struct 
> drm_dp_mst_topology_mgr *mgr,
>   kfree(txmsg);
>  fail_put:
>   drm_dp_mst_topology_put_mstb(mstb);
> - drm_dp_mst_topology_put_port(port);
>   return ret;
>  }
>  
> @@ -2256,15 +2249,16 @@ static int drm_dp_destroy_payload_step2(struct 
> drm_dp_mst_topology_mgr *mgr,
>   */
>  int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
>  {
> - int i, j;
> - int cur_slots = 1;
>   struct drm_dp_payload req_payload;
>   struct drm_dp_mst_port *port;
> + int i, j;
> + int cur_slots = 1;
>  
>   mutex_lock(>payload_lock);
>   for (i = 0; i < mgr->max_payloads; i++) {
>   struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
>   struct drm_dp_payload *payload = >payloads[i];
> + bool put_port = false;
>  
>   /* solve the current payloads - compare to the hw ones
>  - update the hw view */
> @@ -2272,12 +2266,20 @@ int drm_dp_update_payload_part1(struct 
> drm_dp_mst_topology_mgr *mgr)
>   if (vcpi) {
>   port = container_of(vcpi, struct drm_dp_mst_port,
>   vcpi);
> - port = drm_dp_mst_topology_get_port_validated(mgr,
> -   port);
> - if (!port) {
> - mutex_unlock(>payload_lock);
> - return -EINVAL;
> +
> + /* Validated ports don't matter if we're releasing
> +  * VCPI
> +  */
> + if (vcpi->num_slots) {
> + port = drm_dp_mst_topology_get_port_validated(
> + mgr, port);
> + if (!port) {
> + mutex_unlock(>payload_lock);
> + return -EINVAL;
> + }
> + put_port = true;
>   }
> +
>   req_payload.num_slots = vcpi->num_slots;
>   req_payload.vcpi = vcpi->vcpi;
>   } else {
> @@ -2309,7 +2311,7 @@ int drm_dp_update_payload_part1(struct 
> drm_dp_mst_topology_mgr *mgr)
>   }
>   cur_slots += req_payload.num_slots;
>  
> - if (port)
> + if (put_port)
>   drm_dp_mst_topology_put_port(port);
>   }
>  
> @@ -3124,6 +3126,8 @@ bool drm_dp_mst_allocate_vcpi(struct 
> drm_dp_mst_topology_mgr *mgr,
>   

[PATCH AUTOSEL 4.20 039/117] drm/amdgpu: Reorder uvd ring init before uvd resume

2019-01-08 Thread Sasha Levin
From: Chris Wilson 

[ Upstream commit 3b34c14fd50c302db091f020f26dd00ede902c80 ]

As amd_uvd_resume() accesses the uvd ring, it must be initialised first
or else we trigger errors like:

[5.595963] [drm] Found UVD firmware Version: 1.87 Family ID: 17
[5.595969] [drm] PSP loading UVD firmware
[5.596266] [ cut here ]
[5.596268] ODEBUG: assert_init not available (active state 0) object type: 
timer_list hint:   (null)
[5.596285] WARNING: CPU: 0 PID: 507 at lib/debugobjects.c:329 
debug_print_object+0x6a/0x80
[5.596286] Modules linked in: amdgpu(+) hid_logitech_hidpp(+) chash 
gpu_sched amd_iommu_v2 ttm drm_kms_helper crc32c_intel drm hid_sony ff_memless 
igb hid_logitech_dj nvme dca i2c_algo_bit nvme_core wmi pinctrl_amd uas 
usb_storage
[5.596299] CPU: 0 PID: 507 Comm: systemd-udevd Tainted: GW 
4.20.0-0.rc1.git4.1.fc30.x86_64 #1
[5.596301] Hardware name: System manufacturer System Product Name/ROG STRIX 
X470-I GAMING, BIOS 0901 07/23/2018
[5.596303] RIP: 0010:debug_print_object+0x6a/0x80
[5.596305] Code: 8b 43 10 83 c2 01 8b 4b 14 4c 89 e6 89 15 e6 82 b0 02 4c 
8b 45 00 48 c7 c7 60 fd 34 a6 48 8b 14 c5 a0 da 08 a6 e8 6a 6a b8 ff <0f> 0b 5b 
83 05 d0 45 3e 01 01 5d 41 5c c3 83 05 c5 45 3e 01 01 c3
[5.596306] RSP: 0018:a02ac863f8c0 EFLAGS: 00010282
[5.596307] RAX:  RBX: a02ac863f8e0 RCX: 0006
[5.596308] RDX: 0007 RSI: 9160e9a7bfe8 RDI: 9160f91d6c60
[5.596310] RBP: a6742740 R08: 0002 R09: 
[5.596311] R10:  R11:  R12: a634ff69
[5.596312] R13: 000b79d0 R14: a80f76d8 R15: 00266000
[5.596313] FS:  7f762abf7940() GS:9160f900() 
knlGS:
[5.596314] CS:  0010 DS:  ES:  CR0: 80050033
[5.596315] CR2: 55fdc593f000 CR3: 0007e999c000 CR4: 003406f0
[5.596317] Call Trace:
[5.596321]  debug_object_assert_init+0x14a/0x180
[5.596327]  del_timer+0x2e/0x90
[5.596383]  amdgpu_fence_process+0x47/0x100 [amdgpu]
[5.596430]  amdgpu_uvd_resume+0xf6/0x120 [amdgpu]
[5.596475]  uvd_v7_0_sw_init+0xe0/0x280 [amdgpu]
[5.596523]  amdgpu_device_init.cold.30+0xf97/0x14b6 [amdgpu]
[5.596563]  ? amdgpu_driver_load_kms+0x53/0x330 [amdgpu]
[5.596604]  amdgpu_driver_load_kms+0x86/0x330 [amdgpu]
[5.596614]  drm_dev_register+0x115/0x150 [drm]
[5.596654]  amdgpu_pci_probe+0xbd/0x120 [amdgpu]
[5.596658]  local_pci_probe+0x41/0x90
[5.596661]  pci_device_probe+0x188/0x1a0
[5.59]  really_probe+0xf8/0x3b0
[5.596669]  driver_probe_device+0xb3/0xf0
[5.596672]  __driver_attach+0xe1/0x110
[5.596674]  ? driver_probe_device+0xf0/0xf0
[5.596676]  bus_for_each_dev+0x79/0xc0
[5.596679]  bus_add_driver+0x155/0x230
[5.596681]  ? 0xc07d9000
[5.596683]  driver_register+0x6b/0xb0
[5.596685]  ? 0xc07d9000
[5.596688]  do_one_initcall+0x5d/0x2be
[5.596691]  ? rcu_read_lock_sched_held+0x79/0x80
[5.596693]  ? kmem_cache_alloc_trace+0x264/0x290
[5.596695]  ? do_init_module+0x22/0x210
[5.596698]  do_init_module+0x5a/0x210
[5.596701]  load_module+0x2137/0x2430
[5.596703]  ? lockdep_hardirqs_on+0xed/0x180
[5.596714]  ? __do_sys_init_module+0x150/0x1a0
[5.596715]  __do_sys_init_module+0x150/0x1a0
[5.596722]  do_syscall_64+0x60/0x1f0
[5.596725]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[5.596726] RIP: 0033:0x7f762b877dee
[5.596728] Code: 48 8b 0d 9d 20 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 
0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 01 
f0 ff ff 73 01 c3 48 8b 0d 6a 20 0c 00 f7 d8 64 89 01 48
[5.596729] RSP: 002b:7ffc777b8558 EFLAGS: 0246 ORIG_RAX: 
00af
[5.596730] RAX: ffda RBX: 55fdc48da320 RCX: 7f762b877dee
[5.596731] RDX: 7f762b9f284d RSI: 006c5fc6 RDI: 55fdc527a060
[5.596732] RBP: 7f762b9f284d R08: 0003 R09: 0002
[5.596733] R10: 55fdc48ad010 R11: 0246 R12: 55fdc527a060
[5.596734] R13: 55fdc48dca20 R14: 0002 R15: 
[5.596740] irq event stamp: 134618
[5.596743] hardirqs last  enabled at (134617): [] 
console_unlock+0x45e/0x610
[5.596744] hardirqs last disabled at (134618): [] 
trace_hardirqs_off_thunk+0x1a/0x1c
[5.596746] softirqs last  enabled at (133146): [] 
__do_softirq+0x365/0x47c
[5.596748] softirqs last disabled at (133139): [] 
irq_exit+0x119/0x120
[5.596749] ---[ end trace eaee508abfebccdc ]---

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108709
Reviewed-by: Christian König 
Signed-off-by: Chris Wilson 
Cc: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 8 
 

Re: [PATCH v2 04/16] drm/dp_mst: Stop releasing VCPI when removing ports from topology

2019-01-08 Thread Wentland, Harry
On 2018-12-19 7:19 p.m., Lyude Paul wrote:
> This has never actually worked, and isn't needed anyway: the driver's
> always going to try to deallocate VCPI when it tears down the display
> that the VCPI belongs to.
> 
> Signed-off-by: Lyude Paul 
> Reviewed-by: Daniel Vetter 
> Cc: David Airlie 
> Cc: Jerry Zuo 
> Cc: Harry Wentland 
> Cc: Juston Li 

Reviewed-by: Harry Wentland 

Harry

> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 8 
>  1 file changed, 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 356a95aba2d8..ef8637f37564 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -1175,8 +1175,6 @@ static void drm_dp_destroy_port(struct kref *kref)
>   struct drm_dp_mst_topology_mgr *mgr = port->mgr;
>  
>   if (!port->input) {
> - port->vcpi.num_slots = 0;
> -
>   kfree(port->cached_edid);
>  
>   /*
> @@ -3491,12 +3489,6 @@ static void drm_dp_destroy_connector_work(struct 
> work_struct *work)
>   drm_dp_port_teardown_pdt(port, port->pdt);
>   port->pdt = DP_PEER_DEVICE_NONE;
>  
> - if (!port->input && port->vcpi.vcpi > 0) {
> - drm_dp_mst_reset_vcpi_slots(mgr, port);
> - drm_dp_update_payload_part1(mgr);
> - drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
> - }
> -
>   drm_dp_mst_put_port_malloc(port);
>   send_hotplug = true;
>   }
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH AUTOSEL 4.20 034/117] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit 520f08df45fbe300ed650da786a74093d658b7e1 ]

When variable refresh rate is active the hardware counter can return
a position >= vtotal. This results in a vpos being returned from
amdgpu_display_get_crtc_scanoutpos that's a positive value. The
positive value indicates to the caller that the display is
currently in scanout when the display is actually still in vblank.

This is because the vfront porch duration is unknown with variable
refresh active and will end when either a page flip occurs or the
timeout specified by the driver/display is reached.

The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
same when the position is below vtotal. When the position is above
vtotal the function will return a value that is effectively -vbl_end,
the size of the vback porch.

The only caller affected by this change is the DRM helper for
calculating vblank timestamps. This change corrects behavior for
calculating the page flip timestamp from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 686a26de50f9..9c940bbed608 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -857,7 +857,12 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device 
*dev,
/* Inside "upper part" of vblank area? Apply corrective offset if so: */
if (in_vbl && (*vpos >= vbl_start)) {
vtotal = mode->crtc_vtotal;
-   *vpos = *vpos - vtotal;
+
+   /* With variable refresh rate displays the vpos can exceed
+* the vtotal value. Clamp to 0 to return -vbl_end instead
+* of guessing the remaining number of lines until scanout.
+*/
+   *vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
}
 
/* Correct for shifted end of vbl at vbl_end. */
-- 
2.19.1

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


[PATCH AUTOSEL 4.20 005/117] drm/amdkfd: fix interrupt spin lock

2019-01-08 Thread Sasha Levin
From: Christian König 

[ Upstream commit 2383a767c0ca06f96534456d8313909017c6c8d0 ]

Vega10 has multiple interrupt rings, so this can be called from multiple
calles at the same time resulting in:

[   71.779334] 
[   71.779406] WARNING: inconsistent lock state
[   71.779478] 4.19.0-rc1+ #44 Tainted: GW
[   71.779565] 
[   71.779637] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
[   71.779740] kworker/6:1/120 [HC0[0]:SC0[0]:HE1:SE1] takes:
[   71.779832] ad761971 (&(>interrupt_lock)->rlock){?...},
at: kgd2kfd_interrupt+0x75/0x100 [amdgpu]
[   71.780058] {IN-HARDIRQ-W} state was registered at:
[   71.780115]   _raw_spin_lock+0x2c/0x40
[   71.780180]   kgd2kfd_interrupt+0x75/0x100 [amdgpu]
[   71.780248]   amdgpu_irq_callback+0x6c/0x150 [amdgpu]
[   71.780315]   amdgpu_ih_process+0x88/0x100 [amdgpu]
[   71.780380]   amdgpu_irq_handler+0x20/0x40 [amdgpu]
[   71.780409]   __handle_irq_event_percpu+0x49/0x2a0
[   71.780436]   handle_irq_event_percpu+0x30/0x70
[   71.780461]   handle_irq_event+0x37/0x60
[   71.780484]   handle_edge_irq+0x83/0x1b0
[   71.780506]   handle_irq+0x1f/0x30
[   71.780526]   do_IRQ+0x53/0x110
[   71.780544]   ret_from_intr+0x0/0x22
[   71.780566]   cpuidle_enter_state+0xaa/0x330
[   71.780591]   do_idle+0x203/0x280
[   71.780610]   cpu_startup_entry+0x6f/0x80
[   71.780634]   start_secondary+0x1b0/0x200
[   71.780657]   secondary_startup_64+0xa4/0xb0

Fix this by always using irq save spin locks.

Signed-off-by: Christian König 
Acked-by: Alex Deucher 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index e4ded890b1cb..6edaf11d69aa 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -688,6 +688,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void 
*ih_ring_entry)
 {
uint32_t patched_ihre[KFD_MAX_RING_ENTRY_SIZE];
bool is_patched = false;
+   unsigned long flags;
 
if (!kfd->init_complete)
return;
@@ -697,7 +698,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void 
*ih_ring_entry)
return;
}
 
-   spin_lock(>interrupt_lock);
+   spin_lock_irqsave(>interrupt_lock, flags);
 
if (kfd->interrupts_active
&& interrupt_is_wanted(kfd, ih_ring_entry,
@@ -706,7 +707,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void 
*ih_ring_entry)
 is_patched ? patched_ihre : ih_ring_entry))
queue_work(kfd->ih_wq, >interrupt_work);
 
-   spin_unlock(>interrupt_lock);
+   spin_unlock_irqrestore(>interrupt_lock, flags);
 }
 
 int kgd2kfd_quiesce_mm(struct mm_struct *mm)
-- 
2.19.1

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


[PATCH AUTOSEL 4.20 004/117] drm/amd/display: Guard against null stream_state in set_crc_source

2019-01-08 Thread Sasha Levin
From: Nicholas Kazlauskas 

[ Upstream commit f41a895026b8cb6f765190de7d2e7bc3ccbbd183 ]

[Why]

The igt@kms_plane@pixel-format-pipe tests can create a sequence where
stream_state is NULL during amdgpu_dm_crtc_set_crc_source which results
in a null pointer dereference.

[How]

Guard against stream_state being NULL before accessing its fields. This
doesn't fix the root cause of the issue so a DRM_ERROR is generated
to still fail the tests.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: David Francis 
Acked-by: Leo Li 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 01fc5717b657..f088ac585978 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -75,6 +75,11 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, 
const char *src_name)
return -EINVAL;
}
 
+   if (!stream_state) {
+   DRM_ERROR("No stream state for CRTC%d\n", crtc->index);
+   return -EINVAL;
+   }
+
/* When enabling CRC, we should also disable dithering. */
if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) {
if (dc_stream_configure_crc(stream_state->ctx->dc,
-- 
2.19.1

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


Re: [PATCH v2 03/16] drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref fails

2019-01-08 Thread Wentland, Harry
On 2018-12-19 7:19 p.m., Lyude Paul wrote:
> While this isn't a complete fix, this will improve the reliability of
> drm_dp_get_last_connected_port_and_mstb() pretty significantly during
> hotplug events, since there's a chance that the in-memory topology tree
> may not be fully updated when drm_dp_get_last_connected_port_and_mstb()
> is called and thus might end up causing our search to fail on an mstb
> whose topology refcount has reached 0, but has not yet been removed from
> it's parent.
> 
> Ideally, we should further fix this problem by ensuring that we deal
> with the potential for racing with a hotplug event, which would look
> like this:
> 
> * drm_dp_payload_send_msg() retrieves the last living relative of mstb
>   with drm_dp_get_last_connected_port_and_mstb()
> * drm_dp_payload_send_msg() starts building payload message
>   At the same time, mstb gets unplugged from the topology and is no
>   longer the actual last living relative of the original mstb
> * drm_dp_payload_send_msg() tries sending the payload message, hub times
>   out
> * Hub timed out, we give up and run away-resulting in the payload being
>   leaked
> 
> This could be fixed by restarting the
> drm_dp_get_last_connected_port_and_mstb() search whenever we get a
> timeout, sending the payload to the new mstb, then repeating until
> either the entire topology is removed from the system or
> drm_dp_get_last_connected_port_and_mstb() fails. But since the above
> race condition is not terribly likely, we'll address that in a later
> patch series once we've improved the recovery handling for VCPI
> allocations in the rest of the DP MST helpers.
> 
> Signed-off-by: Lyude Paul 
> Cc: Daniel Vetter 
> Cc: David Airlie 
> Cc: Jerry Zuo 
> Cc: Harry Wentland 
> Cc: Juston Li 

Reviewed-by: Harry Wentland 

Harry

> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 55 +--
>  1 file changed, 44 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index b380ada09e90..356a95aba2d8 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -2043,25 +2043,50 @@ static struct drm_dp_mst_port 
> *drm_dp_get_last_connected_port_to_mstb(struct drm
>   return 
> drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
>  }
>  
> -static struct drm_dp_mst_branch 
> *drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
> -  struct 
> drm_dp_mst_branch *mstb,
> -  int 
> *port_num)
> +/**
> + * drm_dp_get_last_connected_port_and_mstb() - Find the last living relatives
> + * in a topology of a given branch device
> + * @mgr: The topology manager to use
> + * @mstb: The disconnected branch device
> + * @port_num: Where to store the number of the last connected port
> + *
> + * Searches upwards in the topology starting from @mstb to try to find the
> + * closest available parent of @mstb that's still connected to the rest of 
> the
> + * topology. This can be used in order to perform operations like releasing
> + * payloads, where the branch device which owned the payload may no longer be
> + * around and thus would require that the payload on the last living relative
> + * be freed instead.
> + *
> + * Returns:
> + * The last connected _dp_mst_branch in the topology that was a parent of
> + * @mstb, if there is one.
> + */
> +static struct drm_dp_mst_branch *
> +drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
> + struct drm_dp_mst_branch *mstb,
> + int *port_num)
>  {
>   struct drm_dp_mst_branch *rmstb = NULL;
>   struct drm_dp_mst_port *found_port;
> +
>   mutex_lock(>lock);
> - if (mgr->mst_primary) {
> + if (!mgr->mst_primary)
> + goto out;
> +
> + do {
>   found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
> + if (!found_port)
> + break;
>  
> - if (found_port) {
> + if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
>   rmstb = found_port->parent;
> - if (drm_dp_mst_topology_try_get_mstb(rmstb)) {
> - *port_num = found_port->port_num;
> - } else {
> - rmstb = NULL;
> - }
> + *port_num = found_port->port_num;
> + } else {
> + /* Search again, starting from this parent */
> + mstb = found_port->parent;
>   }
> - }
> + } while (!rmstb);
> +out:
>   mutex_unlock(>lock);
>   return rmstb;
>  }
> @@ -2110,6 +2135,14 @@ static int drm_dp_payload_send_msg(struct 
> drm_dp_mst_topology_mgr *mgr,

Re: [PATCH v4 02/16] drm/dp_mst: Introduce new refcounting scheme for mstbs and ports

2019-01-08 Thread Wentland, Harry


On 2019-01-04 7:14 p.m., Lyude Paul wrote:
> The current way of handling refcounting in the DP MST helpers is really
> confusing and probably just plain wrong because it's been hacked up many
> times over the years without anyone actually going over the code and
> seeing if things could be simplified.
> 
> To the best of my understanding, the current scheme works like this:
> drm_dp_mst_port and drm_dp_mst_branch both have a single refcount. When
> this refcount hits 0 for either of the two, they're removed from the
> topology state, but not immediately freed. Both ports and branch devices
> will reinitialize their kref once it's hit 0 before actually destroying
> themselves. The intended purpose behind this is so that we can avoid
> problems like not being able to free a remote payload that might still
> be active, due to us having removed all of the port/branch device
> structures in memory, as per:
> 
> commit 91a25e463130 ("drm/dp/mst: deallocate payload on port destruction")
> 
> Which may have worked, but then it caused use-after-free errors. Being
> new to MST at the time, I tried fixing it;
> 
> commit 263efde31f97 ("drm/dp/mst: Get validated port ref in 
> drm_dp_update_payload_part1()")
> 
> But, that was broken: both drm_dp_mst_port and drm_dp_mst_branch structs
> are validated in almost every DP MST helper function. Simply put, this
> means we go through the topology and try to see if the given
> drm_dp_mst_branch or drm_dp_mst_port is still attached to something
> before trying to use it in order to avoid dereferencing freed memory
> (something that has happened a LOT in the past with this library).
> Because of this it doesn't actually matter whether or not we keep keep
> the ports and branches around in memory as that's not enough, because
> any function that validates the branches and ports passed to it will
> still reject them anyway since they're no longer in the topology
> structure. So, use-after-free errors were fixed but payload deallocation
> was completely broken.
> 
> Two years later, AMD informed me about this issue and I attempted to
> come up with a temporary fix, pending a long-overdue cleanup of this
> library:
> 
> commit c54c7374ff44 ("drm/dp_mst: Skip validating ports during destruction, 
> just ref")
> 
> But then that introduced use-after-free errors, so I quickly reverted
> it:
> 
> commit 9765635b3075 ("Revert "drm/dp_mst: Skip validating ports during 
> destruction, just ref"")
> 
> And in the process, learned that there is just no simple fix for this:
> the design is just broken. Unfortuntely, the usage of these helpers are
> quite broken as well. Some drivers like i915 have been smart enough to
> avoid accessing any kind of information from MST port structures, but
> others like nouveau have assumed, understandably so, that
> drm_dp_mst_port structures are normal and can just be accessed at any
> time without worrying about use-after-free errors.
> 
> After a lot of discussion, me and Daniel Vetter came up with a better
> idea to replace all of this.
> 
> To summarize, since this is documented far more indepth in the
> documentation this patch introduces, we make it so that drm_dp_mst_port
> and drm_dp_mst_branch structures have two different classes of
> refcounts: topology_kref, and malloc_kref. topology_kref corresponds to
> the lifetime of the given drm_dp_mst_port or drm_dp_mst_branch in it's
> given topology. Once it hits zero, any associated connectors are removed
> and the branch or port can no longer be validated. malloc_kref
> corresponds to the lifetime of the memory allocation for the actual
> structure, and will always be non-zero so long as the topology_kref is
> non-zero. This gives us a way to allow callers to hold onto port and
> branch device structures past their topology lifetime, and dramatically
> simplifies the lifetimes of both structures. This also finally fixes the
> port deallocation problem, properly.
> 
> Additionally: since this now means that we can keep ports and branch
> devices allocated in memory for however long we need, we no longer need
> a significant amount of the port validation that we currently do.
> 
> Additionally, there is one last scenario that this fixes, which couldn't
> have been fixed properly beforehand:
> 
> - CPU1 unrefs port from topology (refcount 1->0)
> - CPU2 refs port in topology(refcount 0->1)
> 
> Since we now can guarantee memory safety for ports and branches
> as-needed, we also can make our main reference counting functions fix
> this problem by using kref_get_unless_zero() internally so that topology
> refcounts can only ever reach 0 once.
> 
> Changes since v2:
> * Fix commit message - checkpatch
> Changes since v1:
> * Remove forward declarations - danvet
> * Move "Branch device and port refcounting" section from documentation
>   into kernel-doc comments - danvet
> * Export internal topology lifetime functions into their own section in
>   the kernel-docs - danvet
> * s/@/&/g for struct 

Re: [PATCH 0/3] drm/amdgpu: Fix suspend/resume issues with MST

2019-01-08 Thread Wentland, Harry
On 2019-01-07 7:56 p.m., Lyude Paul wrote:
> Fix the suspend/issues that Jerry Zuo found in amdgpu, and add some
> compiler warnings for drivers ignoring the return code of
> drm_dp_mst_topology_mgr_resume() to help ensure we don't need to fix
> this again in the future for someone else's driver.
> 
> Cc: Jerry Zuo 

With the small change Daniel mentioned this series is
Reviewed-by: Harry Wentland 

Harry

> 
> Lyude Paul (3):
>   drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume()
>   drm/amdgpu: Don't fail resume process if resuming atomic state fails
>   drm/dp_mst: Add __must_check to drm_dp_mst_topology_mgr_resume()
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 37 +--
>  drivers/gpu/drm/drm_dp_mst_topology.c |  3 +-
>  include/drm/drm_dp_mst_helper.h   |  3 +-
>  3 files changed, 29 insertions(+), 14 deletions(-)
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 3/4] drm/radeon: Use drm_hdmi_avi_infoframe_quant_range()

2019-01-08 Thread Ville Syrjala
From: Ville Syrjälä 

Fill out the AVI infoframe quantization range bits using
drm_hdmi_avi_infoframe_quant_range() instead of hand rolling it.

This changes the behaviour slightly as
drm_hdmi_avi_infoframe_quant_range() will set a non-zero Q bit
even when QS==0 iff the Q bit matched the default quantization
range for the given mode. This matches the recommendation in
HDMI 2.0 and is allowed even before that.

Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "David (ChunMing) Zhou" 
Cc: amd-gfx@lists.freedesktop.org
Signed-off-by: Ville Syrjälä 
Acked-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_audio.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_audio.c 
b/drivers/gpu/drm/radeon/radeon_audio.c
index 5a7d48339b32..708765bf9e66 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -523,14 +523,11 @@ static int radeon_audio_set_avi_packet(struct drm_encoder 
*encoder,
}
 
if (radeon_encoder->output_csc != RADEON_OUTPUT_CSC_BYPASS) {
-   if 
(drm_rgb_quant_range_selectable(radeon_connector_edid(connector))) {
-   if (radeon_encoder->output_csc == 
RADEON_OUTPUT_CSC_TVRGB)
-   frame.quantization_range = 
HDMI_QUANTIZATION_RANGE_LIMITED;
-   else
-   frame.quantization_range = 
HDMI_QUANTIZATION_RANGE_FULL;
-   } else {
-   frame.quantization_range = 
HDMI_QUANTIZATION_RANGE_DEFAULT;
-   }
+   drm_hdmi_avi_infoframe_quant_range(, connector, mode,
+  radeon_encoder->output_csc 
== RADEON_OUTPUT_CSC_TVRGB ?
+  
HDMI_QUANTIZATION_RANGE_LIMITED :
+  HDMI_QUANTIZATION_RANGE_FULL,
+  
drm_rgb_quant_range_selectable(radeon_connector_edid(connector)));
}
 
err = hdmi_avi_infoframe_pack(, buffer, sizeof(buffer));
-- 
2.19.2

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


[PATCH 1/4] drm/edid: Pass connector to AVI infoframe functions

2019-01-08 Thread Ville Syrjala
From: Ville Syrjälä 

Make life easier for drivers by simply passing the connector
to drm_hdmi_avi_infoframe_from_display_mode() and
drm_hdmi_avi_infoframe_quant_range(). That way drivers don't
need to worry about is_hdmi2_sink mess.

v2: Make is_hdmi2_sink() return true for sil-sii8620
Adapt to omap/vc4 changes

Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "David (ChunMing) Zhou" 
Cc: Archit Taneja 
Cc: Andrzej Hajda 
Cc: Laurent Pinchart 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Russell King 
Cc: CK Hu 
Cc: Philipp Zabel 
Cc: Rob Clark 
Cc: Ben Skeggs 
Cc: Tomi Valkeinen 
Cc: Sandy Huang 
Cc: "Heiko Stübner" 
Cc: Benjamin Gaignard 
Cc: Vincent Abriou 
Cc: Thierry Reding 
Cc: Eric Anholt 
Cc: Shawn Guo 
Cc: Ilia Mirkin 
Cc: amd-gfx@lists.freedesktop.org
Cc: linux-arm-...@vger.kernel.org
Cc: freedr...@lists.freedesktop.org
Cc: nouv...@lists.freedesktop.org
Cc: linux-te...@vger.kernel.org
Signed-off-by: Ville Syrjälä 
Acked-by: Thierry Reding 
Acked-by: Russell King 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c|  2 +-
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c|  2 +-
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c |  2 +-
 drivers/gpu/drm/bridge/analogix-anx78xx.c |  5 ++--
 drivers/gpu/drm/bridge/sii902x.c  |  3 ++-
 drivers/gpu/drm/bridge/sil-sii8620.c  |  3 +--
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |  3 ++-
 drivers/gpu/drm/drm_edid.c| 33 ++-
 drivers/gpu/drm/exynos/exynos_hdmi.c  |  3 ++-
 drivers/gpu/drm/i2c/tda998x_drv.c |  3 ++-
 drivers/gpu/drm/i915/intel_hdmi.c | 14 +-
 drivers/gpu/drm/i915/intel_lspcon.c   | 15 ++-
 drivers/gpu/drm/i915/intel_sdvo.c | 10 ---
 drivers/gpu/drm/mediatek/mtk_hdmi.c   |  3 ++-
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c|  3 ++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  7 +++--
 drivers/gpu/drm/omapdrm/omap_encoder.c|  4 +--
 drivers/gpu/drm/radeon/radeon_audio.c |  2 +-
 drivers/gpu/drm/rockchip/inno_hdmi.c  |  4 ++-
 drivers/gpu/drm/sti/sti_hdmi.c|  3 ++-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c|  3 ++-
 drivers/gpu/drm/tegra/hdmi.c  |  3 ++-
 drivers/gpu/drm/tegra/sor.c   |  3 ++-
 drivers/gpu/drm/vc4/vc4_hdmi.c|  9 ---
 drivers/gpu/drm/zte/zx_hdmi.c |  4 ++-
 include/drm/drm_edid.h|  8 +++---
 27 files changed, 91 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 4cfecdce29a3..1f0426d2fc2a 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1682,7 +1682,7 @@ static void dce_v10_0_afmt_setmode(struct drm_encoder 
*encoder,
dce_v10_0_audio_write_sad_regs(encoder);
dce_v10_0_audio_write_latency_fields(encoder, mode);
 
-   err = drm_hdmi_avi_infoframe_from_display_mode(, mode, false);
+   err = drm_hdmi_avi_infoframe_from_display_mode(, connector, mode);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 7c868916d90f..2280b971d758 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -1724,7 +1724,7 @@ static void dce_v11_0_afmt_setmode(struct drm_encoder 
*encoder,
dce_v11_0_audio_write_sad_regs(encoder);
dce_v11_0_audio_write_latency_fields(encoder, mode);
 
-   err = drm_hdmi_avi_infoframe_from_display_mode(, mode, false);
+   err = drm_hdmi_avi_infoframe_from_display_mode(, connector, mode);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c 
b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 17eaaba36017..db443ec53d3a 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1423,6 +1423,7 @@ static void dce_v6_0_audio_set_avi_infoframe(struct 
drm_encoder *encoder,
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
+   struct drm_connector *connector = 
amdgpu_get_connector_for_encoder(encoder);
struct hdmi_avi_infoframe frame;
u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
uint8_t *payload = buffer + 3;
@@ -1430,7 +1431,7 @@ static void dce_v6_0_audio_set_avi_infoframe(struct 
drm_encoder *encoder,
ssize_t err;
u32 tmp;
 
-   err = drm_hdmi_avi_infoframe_from_display_mode(, mode, false);
+   err = drm_hdmi_avi_infoframe_from_display_mode(, connector, 

[PATCH 4/4] drm/edid: Add display_info.rgb_quant_range_selectable

2019-01-08 Thread Ville Syrjala
From: Ville Syrjälä 

Move the CEA-861 QS bit handling entirely into the edid code. No
need to bother the drivers with this.

Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "David (ChunMing) Zhou" 
Cc: amd-gfx@lists.freedesktop.org
Cc: Eric Anholt  (supporter:DRM DRIVERS FOR VC4)
Signed-off-by: Ville Syrjälä 
Acked-by: Alex Deucher 
Acked-by: Eric Anholt 
---
 drivers/gpu/drm/drm_edid.c| 70 ---
 drivers/gpu/drm/i915/intel_drv.h  |  1 -
 drivers/gpu/drm/i915/intel_hdmi.c |  8 +--
 drivers/gpu/drm/i915/intel_lspcon.c   |  3 +-
 drivers/gpu/drm/i915/intel_sdvo.c |  7 +--
 drivers/gpu/drm/radeon/radeon_audio.c |  3 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c|  9 +---
 include/drm/drm_connector.h   |  6 +++
 include/drm/drm_edid.h|  4 +-
 9 files changed, 43 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index cd25bd08bf53..990b1909f9d7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3641,6 +3641,20 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
return oui == HDMI_FORUM_IEEE_OUI;
 }
 
+static bool cea_db_is_vcdb(const u8 *db)
+{
+   if (cea_db_tag(db) != USE_EXTENDED_TAG)
+   return false;
+
+   if (cea_db_payload_len(db) != 2)
+   return false;
+
+   if (cea_db_extended_tag(db) != EXT_VIDEO_CAPABILITY_BLOCK)
+   return false;
+
+   return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -4223,41 +4237,6 @@ bool drm_detect_monitor_audio(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_detect_monitor_audio);
 
-/**
- * drm_rgb_quant_range_selectable - is RGB quantization range selectable?
- * @edid: EDID block to scan
- *
- * Check whether the monitor reports the RGB quantization range selection
- * as supported. The AVI infoframe can then be used to inform the monitor
- * which quantization range (full or limited) is used.
- *
- * Return: True if the RGB quantization range is selectable, false otherwise.
- */
-bool drm_rgb_quant_range_selectable(struct edid *edid)
-{
-   u8 *edid_ext;
-   int i, start, end;
-
-   edid_ext = drm_find_cea_extension(edid);
-   if (!edid_ext)
-   return false;
-
-   if (cea_db_offsets(edid_ext, , ))
-   return false;
-
-   for_each_cea_db(edid_ext, i, start, end) {
-   if (cea_db_tag(_ext[i]) == USE_EXTENDED_TAG &&
-   cea_db_payload_len(_ext[i]) == 2 &&
-   cea_db_extended_tag(_ext[i]) ==
-   EXT_VIDEO_CAPABILITY_BLOCK) {
-   DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
-   return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
-   }
-   }
-
-   return false;
-}
-EXPORT_SYMBOL(drm_rgb_quant_range_selectable);
 
 /**
  * drm_default_rgb_quant_range - default RGB quantization range
@@ -4278,6 +4257,16 @@ drm_default_rgb_quant_range(const struct 
drm_display_mode *mode)
 }
 EXPORT_SYMBOL(drm_default_rgb_quant_range);
 
+static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
+{
+   struct drm_display_info *info = >display_info;
+
+   DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", db[2]);
+
+   if (db[2] & EDID_CEA_VCDB_QS)
+   info->rgb_quant_range_selectable = true;
+}
+
 static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
   const u8 *db)
 {
@@ -4452,6 +4441,8 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
drm_parse_hdmi_forum_vsdb(connector, db);
if (cea_db_is_y420cmdb(db))
drm_parse_y420cmdb_bitmap(connector, db);
+   if (cea_db_is_vcdb(db))
+   drm_parse_vcdb(connector, db);
}
 }
 
@@ -4472,6 +4463,7 @@ drm_reset_display_info(struct drm_connector *connector)
info->max_tmds_clock = 0;
info->dvi_dual = false;
info->has_hdmi_infoframe = false;
+   info->rgb_quant_range_selectable = false;
memset(>hdmi, 0, sizeof(info->hdmi));
 
info->non_desktop = 0;
@@ -4939,15 +4931,15 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
  * @connector: the connector
  * @mode: DRM display mode
  * @rgb_quant_range: RGB quantization range (Q)
- * @rgb_quant_range_selectable: Sink support selectable RGB quantization range 
(QS)
  */
 void
 drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
   struct drm_connector *connector,
   const struct drm_display_mode *mode,
-  enum hdmi_quantization_range rgb_quant_range,
-  bool rgb_quant_range_selectable)
+  enum hdmi_quantization_range rgb_quant_range)
 {
+   const 

[PATCH 25/25] drm/amd/display: 3.2.14

2019-01-08 Thread sunpeng.li
From: Steven Chiu 

Signed-off-by: Steven Chiu 
Reviewed-by: Yongqiang Sun 
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 98f716be..f362b04 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.13"
+#define DC_VER "3.2.14"
 
 #define MAX_SURFACES 3
 #define MAX_STREAMS 6
-- 
2.7.4

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


[PATCH 23/25] drm/amd/display: Check if registers are available before accessing

2019-01-08 Thread sunpeng.li
From: Eric Bernstein 

Check if VERT_FILTER_INIT_BOT and BLACK_OFFSET registers
exists in the DCN SCL IP block before trying to access.

Signed-off-by: Eric Bernstein 
Reviewed-by: Dmytro Laktyushkin 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c  | 42 --
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
index 4a863a5d..c7642e7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
@@ -597,11 +597,13 @@ static void dpp1_dscl_set_manual_ratio_init(
SCL_V_INIT_FRAC, init_frac,
SCL_V_INIT_INT, init_int);
 
-   init_frac = dc_fixpt_u0d19(data->inits.v_bot) << 5;
-   init_int = dc_fixpt_floor(data->inits.v_bot);
-   REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
-   SCL_V_INIT_FRAC_BOT, init_frac,
-   SCL_V_INIT_INT_BOT, init_int);
+   if (REG(SCL_VERT_FILTER_INIT_BOT)) {
+   init_frac = dc_fixpt_u0d19(data->inits.v_bot) << 5;
+   init_int = dc_fixpt_floor(data->inits.v_bot);
+   REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
+   SCL_V_INIT_FRAC_BOT, init_frac,
+   SCL_V_INIT_INT_BOT, init_int);
+   }
 
init_frac = dc_fixpt_u0d19(data->inits.v_c) << 5;
init_int = dc_fixpt_floor(data->inits.v_c);
@@ -609,11 +611,13 @@ static void dpp1_dscl_set_manual_ratio_init(
SCL_V_INIT_FRAC_C, init_frac,
SCL_V_INIT_INT_C, init_int);
 
-   init_frac = dc_fixpt_u0d19(data->inits.v_c_bot) << 5;
-   init_int = dc_fixpt_floor(data->inits.v_c_bot);
-   REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
-   SCL_V_INIT_FRAC_BOT_C, init_frac,
-   SCL_V_INIT_INT_BOT_C, init_int);
+   if (REG(SCL_VERT_FILTER_INIT_BOT_C)) {
+   init_frac = dc_fixpt_u0d19(data->inits.v_c_bot) << 5;
+   init_int = dc_fixpt_floor(data->inits.v_c_bot);
+   REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
+   SCL_V_INIT_FRAC_BOT_C, init_frac,
+   SCL_V_INIT_INT_BOT_C, init_int);
+   }
 }
 
 
@@ -688,15 +692,17 @@ void dpp1_dscl_set_scaler_manual_scale(
return;
 
/* Black offsets */
-   if (ycbcr)
-   REG_SET_2(SCL_BLACK_OFFSET, 0,
-   SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y,
-   SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR);
-   else
+   if (REG(SCL_BLACK_OFFSET)) {
+   if (ycbcr)
+   REG_SET_2(SCL_BLACK_OFFSET, 0,
+   SCL_BLACK_OFFSET_RGB_Y, 
BLACK_OFFSET_RGB_Y,
+   SCL_BLACK_OFFSET_CBCR, 
BLACK_OFFSET_CBCR);
+   else
 
-   REG_SET_2(SCL_BLACK_OFFSET, 0,
-   SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y,
-   SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
+   REG_SET_2(SCL_BLACK_OFFSET, 0,
+   SCL_BLACK_OFFSET_RGB_Y, 
BLACK_OFFSET_RGB_Y,
+   SCL_BLACK_OFFSET_CBCR, 
BLACK_OFFSET_RGB_Y);
+   }
 
/* Manually calculate scale ratio and init values */
dpp1_dscl_set_manual_ratio_init(dpp, scl_data);
-- 
2.7.4

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


[PATCH 20/25] drm/amd/display: add workaround for 4k video underflow

2019-01-08 Thread sunpeng.li
From: Eric Yang 

[Why]
On DCN1, there is an issue where on high BW config on single channel
systems, underflow will be observed if DCC is disabled. This issue
can be observed on several use cases. For this particular case,
it is observed when playing 4k video on 4k desktop with video downscaled
to a certain size.

[How]
Block MPO for this particular case, this will prevent extra BW consumed
from downscaling, working around the underflow.

Signed-off-by: Eric Yang 
Reviewed-by: Yongqiang Sun 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c  | 51 ++
 1 file changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 3e6a602..ea0628b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1131,6 +1131,56 @@ static enum dc_status dcn10_validate_plane(const struct 
dc_plane_state *plane_st
return DC_OK;
 }
 
+static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state 
*context)
+{
+   int i, j;
+   bool video_down_scaled = false;
+   bool video_large = false;
+   bool desktop_large = false;
+   bool dcc_disabled = false;
+
+   for (i = 0; i < context->stream_count; i++) {
+   if (context->stream_status[i].plane_count == 0)
+   continue;
+
+   if (context->stream_status[i].plane_count > 2)
+   return false;
+
+   for (j = 0; j < context->stream_status[i].plane_count; j++) {
+   struct dc_plane_state *plane =
+   context->stream_status[i].plane_states[j];
+
+
+   if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+
+   if (plane->src_rect.width > 
plane->dst_rect.width ||
+   plane->src_rect.height > 
plane->dst_rect.height)
+   video_down_scaled = true;
+
+   if (plane->src_rect.width >= 3840)
+   video_large = true;
+
+   } else {
+   if (plane->src_rect.width >= 3840)
+   desktop_large = true;
+   if (!plane->dcc.enable)
+   dcc_disabled = true;
+   }
+   }
+   }
+
+   /*
+* Workaround: On DCN10 there is UMC issue that causes underflow when
+* playing 4k video on 4k desktop with video downscaled and single 
channel
+* memory
+*/
+   if (video_large && desktop_large && video_down_scaled && dcc_disabled &&
+   dc->dcn_soc->number_of_channels == 1)
+   return DC_FAIL_SURFACE_VALIDATE;
+
+   return DC_OK;
+}
+
 static enum dc_status dcn10_get_default_swizzle_mode(struct dc_plane_state 
*plane_state)
 {
enum dc_status result = DC_OK;
@@ -1159,6 +1209,7 @@ static const struct resource_funcs dcn10_res_pool_funcs = 
{
.validate_bandwidth = dcn_validate_bandwidth,
.acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
.validate_plane = dcn10_validate_plane,
+   .validate_global = dcn10_validate_global,
.add_stream_to_ctx = dcn10_add_stream_to_ctx,
.get_default_swizzle_mode = dcn10_get_default_swizzle_mode
 };
-- 
2.7.4

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


[PATCH 13/25] drm/amd/display: Shift dc link aux to aux_payload

2019-01-08 Thread sunpeng.li
From: David Francis 

[Why]
aux_payload should be the struct used inside dc to start
aux transactions.  This will allow the old aux interface
to be seamlessly replaced.

[How]
Add three fields to aux_payload: reply, mot, defer_delay
This will mean that aux_payload has all data required
to submit a request.  Shift dc_link to use this struct

Signed-off-by: David Francis 
Reviewed-by: Harry Wentland 
Acked-by: Leo Li 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c| 84 --
 drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c  | 57 ++-
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c   |  3 +-
 drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h   | 11 ++-
 .../gpu/drm/amd/display/include/i2caux_interface.h | 10 +++
 5 files changed, 70 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 1b0d209..b400963 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -35,6 +35,8 @@
 
 #include "dc_link_ddc.h"
 
+#include "i2caux_interface.h"
+
 /* #define TRACE_DPCD */
 
 #ifdef TRACE_DPCD
@@ -81,80 +83,24 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
  struct drm_dp_aux_msg *msg)
 {
ssize_t result = 0;
-   enum i2caux_transaction_action action;
-   enum aux_transaction_type type;
+   struct aux_payload payload;
 
if (WARN_ON(msg->size > 16))
return -E2BIG;
 
-   switch (msg->request & ~DP_AUX_I2C_MOT) {
-   case DP_AUX_NATIVE_READ:
-   type = AUX_TRANSACTION_TYPE_DP;
-   action = I2CAUX_TRANSACTION_ACTION_DP_READ;
-
-   result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
- msg->address,
- >reply,
- msg->buffer,
- msg->size,
- type,
- action);
-   break;
-   case DP_AUX_NATIVE_WRITE:
-   type = AUX_TRANSACTION_TYPE_DP;
-   action = I2CAUX_TRANSACTION_ACTION_DP_WRITE;
-
-   dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
-msg->address,
->reply,
-msg->buffer,
-msg->size,
-type,
-action);
-   result = msg->size;
-   break;
-   case DP_AUX_I2C_READ:
-   type = AUX_TRANSACTION_TYPE_I2C;
-   if (msg->request & DP_AUX_I2C_MOT)
-   action = I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
-   else
-   action = I2CAUX_TRANSACTION_ACTION_I2C_READ;
-
-   result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
- msg->address,
- >reply,
- msg->buffer,
- msg->size,
- type,
- action);
-   break;
-   case DP_AUX_I2C_WRITE:
-   type = AUX_TRANSACTION_TYPE_I2C;
-   if (msg->request & DP_AUX_I2C_MOT)
-   action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
-   else
-   action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
-
-   dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
-msg->address,
->reply,
-msg->buffer,
-msg->size,
-type,
-action);
-   result = msg->size;
-   break;
-   default:
-   return -EINVAL;
-   }
+   payload.address = msg->address;
+   payload.data = msg->buffer;
+   payload.length = msg->size;
+   payload.reply = >reply;
+   payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0;
+   payload.write = (msg->request & DP_AUX_I2C_READ) == 0;
+   payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0;
+   payload.defer_delay = 0;
 
-#ifdef TRACE_DPCD
-   log_dpcd(msg->request,
-msg->address,
-msg->buffer,
-msg->size,
-r == DDC_RESULT_SUCESSFULL);
-#endif
+   result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, );
+
+   if (payload.write)
+   result = msg->size;
 
if 

[PATCH 15/25] drm/amd/display: Change from aux_engine to dce_aux

2019-01-08 Thread sunpeng.li
From: David Francis 

[Why]
The aux_engine struct is needlessly complex and
is defined multiple times.  It contains function pointers
that each have only one version and are called only from
inside dce_aux.

[How]
Replace aux_engine with a new struct called dce_aux.
Remove all function pointers and call functions directly.
Remove unused functions

Signed-off-by: David Francis 
Reviewed-by: Harry Wentland 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c   | 557 +
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.h   |  20 +-
 .../drm/amd/display/dc/dce100/dce100_resource.c|   2 +-
 .../drm/amd/display/dc/dce110/dce110_resource.c|   2 +-
 .../drm/amd/display/dc/dce112/dce112_resource.c|   2 +-
 .../drm/amd/display/dc/dce120/dce120_resource.c|   2 +-
 .../gpu/drm/amd/display/dc/dce80/dce80_resource.c  |   2 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c  |   4 +-
 drivers/gpu/drm/amd/display/dc/inc/core_types.h|   2 +-
 9 files changed, 45 insertions(+), 548 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index 5660615..adbb222 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -42,17 +42,17 @@
container_of((ptr), struct aux_engine_dce110, base)
 
 #define FROM_ENGINE(ptr) \
-   FROM_AUX_ENGINE(container_of((ptr), struct aux_engine, base))
+   FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base))
 
 #define FROM_AUX_ENGINE_ENGINE(ptr) \
-   container_of((ptr), struct aux_engine, base)
+   container_of((ptr), struct dce_aux, base)
 enum {
AUX_INVALID_REPLY_RETRY_COUNTER = 1,
AUX_TIMED_OUT_RETRY_COUNTER = 2,
AUX_DEFER_RETRY_COUNTER = 6
 };
 static void release_engine(
-   struct aux_engine *engine)
+   struct dce_aux *engine)
 {
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
 
@@ -67,7 +67,7 @@ static void release_engine(
 #define DMCU_CAN_ACCESS_AUX 2
 
 static bool is_engine_available(
-   struct aux_engine *engine)
+   struct dce_aux *engine)
 {
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
 
@@ -80,7 +80,7 @@ static bool is_engine_available(
return (field != DMCU_CAN_ACCESS_AUX);
 }
 static bool acquire_engine(
-   struct aux_engine *engine)
+   struct dce_aux *engine)
 {
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
 
@@ -156,7 +156,7 @@ static bool acquire_engine(
(0xFF & (address))
 
 static void submit_channel_request(
-   struct aux_engine *engine,
+   struct dce_aux *engine,
struct aux_request_transaction_data *request)
 {
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
@@ -248,7 +248,7 @@ static void submit_channel_request(
REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
 }
 
-static int read_channel_reply(struct aux_engine *engine, uint32_t size,
+static int read_channel_reply(struct dce_aux *engine, uint32_t size,
  uint8_t *buffer, uint8_t *reply_result,
  uint32_t *sw_status)
 {
@@ -301,61 +301,8 @@ static int read_channel_reply(struct aux_engine *engine, 
uint32_t size,
return 0;
 }
 
-static void process_channel_reply(
-   struct aux_engine *engine,
-   struct aux_reply_transaction_data *reply)
-{
-   int bytes_replied;
-   uint8_t reply_result;
-   uint32_t sw_status;
-
-   bytes_replied = read_channel_reply(engine, reply->length, reply->data,
-  _result, _status);
-
-   /* in case HPD is LOW, exit AUX transaction */
-   if ((sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) {
-   reply->status = AUX_TRANSACTION_REPLY_HPD_DISCON;
-   return;
-   }
-
-   if (bytes_replied < 0) {
-   /* Need to handle an error case...
-* Hopefully, upper layer function won't call this function if
-* the number of bytes in the reply was 0, because there was
-* surely an error that was asserted that should have been
-* handled for hot plug case, this could happens
-*/
-   if (!(sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) {
-   reply->status = AUX_TRANSACTION_REPLY_INVALID;
-   ASSERT_CRITICAL(false);
-   return;
-   }
-   } else {
-
-   switch (reply_result) {
-   case 0: /* ACK */
-   reply->status = AUX_TRANSACTION_REPLY_AUX_ACK;
-   break;
-   case 1: /* NACK */
-   reply->status = AUX_TRANSACTION_REPLY_AUX_NACK;
-   break;
-   case 2: /* DEFER */
-   reply->status = AUX_TRANSACTION_REPLY_AUX_DEFER;
-   break;
-   

[PATCH 24/25] drm/amd/display: Check for NULL when creating gamma struct

2019-01-08 Thread sunpeng.li
From: Krunoslav Kovac 

[Wjy] Some stress test is causing unexpected memory allocation
failure. This prevents null dereference but there will likely be problems
later, hard to gracefully handle memalloc fail for critical objects.

Signed-off-by: Krunoslav Kovac 
Reviewed-by: Anthony Koo 
Acked-by: Leo Li 
Acked-by: Reza Amini 
---
 drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index c60c9b4..ee6bd50 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -40,11 +40,14 @@ static void construct(struct dc_context *ctx, struct 
dc_plane_state *plane_state
plane_state->ctx = ctx;
 
plane_state->gamma_correction = dc_create_gamma();
-   plane_state->gamma_correction->is_identity = true;
+   if (plane_state->gamma_correction != NULL)
+   plane_state->gamma_correction->is_identity = true;
 
plane_state->in_transfer_func = dc_create_transfer_func();
-   plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-   plane_state->in_transfer_func->ctx = ctx;
+   if (plane_state->in_transfer_func != NULL) {
+   plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
+   plane_state->in_transfer_func->ctx = ctx;
+   }
 }
 
 static void destruct(struct dc_plane_state *plane_state)
-- 
2.7.4

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


[PATCH 03/25] drm/amd/display: Pack DMCU iRAM alignment

2019-01-08 Thread sunpeng.li
From: Josip Pavic 

[Why]
When the DMCU's iRAM definition was moved to the newly created
power_helpers, a #pragma pack was lost, causing the iRAM to be misaligned

[How]
Restore the #pragma pack

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

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 00f63b7..c11a443 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -57,6 +57,7 @@ static const unsigned char 
abm_config[abm_defines_max_config][abm_defines_max_le
 #define NUM_POWER_FN_SEGS 8
 #define NUM_BL_CURVE_SEGS 16
 
+#pragma pack(push, 1)
 /* NOTE: iRAM is 256B in size */
 struct iram_table_v_2 {
/* flags  */
@@ -100,6 +101,7 @@ struct iram_table_v_2 {
uint8_t dummy8; /* 0xfe 
  */
uint8_t dummy9; /* 0xff 
  */
 };
+#pragma pack(pop)
 
 static uint16_t backlight_8_to_16(unsigned int backlight_8bit)
 {
-- 
2.7.4

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


[PATCH 14/25] drm/amd/display: Switch ddc to new aux interface

2019-01-08 Thread sunpeng.li
From: David Francis 

[Why]
The old aux interface goes through i2caux and the aux_engine
and engine function pointers.  The multiple layers of indirection
make it hard to tell waht is happening.  The aux algorithm
does not need to be this complicated: attempt to submit the
request.  If you get an ack (reply = 0), stop.  Otherwise,
retry, up to 7 times.

[How]
Add a new helper function in dce_aux that performs aux retries

Move the plumbing of the aux calling code into dce_aux

Add functions in ddc that redirect directly to dce_aux

Make all aux calls use these functions

Signed-off-by: David Francis 
Reviewed-by: Harry Wentland 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | 175 --
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |  99 
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.h  |   6 +
 drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h  |  12 +-
 4 files changed, 137 insertions(+), 155 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 5ac6573..a343b8b 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
@@ -34,6 +34,7 @@
 #include "core_types.h"
 #include "dc_link_ddc.h"
 #include "aux_engine.h"
+#include "dce/dce_aux.h"
 
 #define AUX_POWER_UP_WA_DELAY 500
 #define I2C_OVER_AUX_DEFER_WA_DELAY 70
@@ -164,43 +165,6 @@ static void dal_ddc_i2c_payloads_destroy(struct 
i2c_payloads **p)
 
 }
 
-static struct aux_payloads *dal_ddc_aux_payloads_create(struct dc_context 
*ctx, uint32_t count)
-{
-   struct aux_payloads *payloads;
-
-   payloads = kzalloc(sizeof(struct aux_payloads), GFP_KERNEL);
-
-   if (!payloads)
-   return NULL;
-
-   if (dal_vector_construct(
-   >payloads, ctx, count, sizeof(struct aux_payload)))
-   return payloads;
-
-   kfree(payloads);
-   return NULL;
-}
-
-static struct aux_payload *dal_ddc_aux_payloads_get(struct aux_payloads *p)
-{
-   return (struct aux_payload *)p->payloads.container;
-}
-
-static uint32_t  dal_ddc_aux_payloads_get_count(struct aux_payloads *p)
-{
-   return p->payloads.count;
-}
-
-static void dal_ddc_aux_payloads_destroy(struct aux_payloads **p)
-{
-   if (!p || !*p)
-   return;
-
-   dal_vector_destruct(&(*p)->payloads);
-   kfree(*p);
-   *p = NULL;
-}
-
 #define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
 
 void dal_ddc_i2c_payloads_add(
@@ -224,32 +188,6 @@ void dal_ddc_i2c_payloads_add(
 
 }
 
-void dal_ddc_aux_payloads_add(
-   struct aux_payloads *payloads,
-   uint32_t address,
-   uint32_t len,
-   uint8_t *data,
-   bool write,
-   bool mot,
-   uint32_t defer_delay)
-{
-   uint32_t payload_size = DEFAULT_AUX_MAX_DATA_SIZE;
-   uint32_t pos;
-
-   for (pos = 0; pos < len; pos += payload_size) {
-   struct aux_payload payload = {
-   .i2c_over_aux = true,
-   .write = write,
-   .address = address,
-   .length = DDC_MIN(payload_size, len - pos),
-   .data = data + pos,
-   .reply = NULL,
-   .mot = mot,
-   .defer_delay = defer_delay};
-   dal_vector_append(>payloads, );
-   }
-}
-
 static void construct(
struct ddc_service *ddc_service,
struct ddc_service_init_data *init_data)
@@ -578,32 +516,34 @@ bool dal_ddc_service_query_ddc_data(
/*TODO: len of payload data for i2c and aux is uint8,
 *  but we want to read 256 over i2c*/
if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
-
-   struct aux_payloads *payloads =
-   dal_ddc_aux_payloads_create(ddc->ctx, payloads_num);
-
-   struct aux_command command = {
-   .payloads = dal_ddc_aux_payloads_get(payloads),
-   .number_of_payloads = 0,
+   struct aux_payload write_payload = {
+   .i2c_over_aux = true,
+   .write = true,
+   .mot = true,
+   .address = address,
+   .length = write_size,
+   .data = write_buf,
+   .reply = NULL,
.defer_delay = get_defer_delay(ddc),
-   .max_defer_write_retry = 0 };
+   };
 
-   dal_ddc_aux_payloads_add(
-   payloads, address, write_size, write_buf, true, true, 
get_defer_delay(ddc));
-
-   dal_ddc_aux_payloads_add(
-   payloads, address, read_size, read_buf, false, false, 
get_defer_delay(ddc));
-
-   command.number_of_payloads =
-   dal_ddc_aux_payloads_get_count(payloads);
+   struct 

[PATCH 12/25] drm/amd/display: 3.2.13

2019-01-08 Thread sunpeng.li
From: Steven Chiu 

Signed-off-by: Steven Chiu 
Reviewed-by: Yongqiang Sun 
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 1c46249..98f716be 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.12"
+#define DC_VER "3.2.13"
 
 #define MAX_SURFACES 3
 #define MAX_STREAMS 6
-- 
2.7.4

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


[PATCH 00/25] DC Patches Jan 08, 2019

2019-01-08 Thread sunpeng.li
From: Leo Li 

Summary of change:
* AUX interface cleanup and refactor
* Fix potential warning storm on Raven
* Fix vanishing cursor bug on Raven


Bayan Zabihiyan (1):
  drm/amd/display: Add new infopacket definition

Charlene Liu (2):
  drm/amd/display: fix PME notification not working in RV desktop
  drm/amd/display: dp interlace MSA timing programming for Interlace
mode.

David Francis (4):
  drm/amd/display: Shift dc link aux to aux_payload
  drm/amd/display: Switch ddc to new aux interface
  drm/amd/display: Change from aux_engine to dce_aux
  drm/amd/display: Remove i2caux folder

Derek Lai (1):
  drm/amd/display: Set link rate set if eDP ver >= 1.4.

Dmytro Laktyushkin (1):
  drm/amd/display: Rename configure_encoder to enc1_configure_encoder

Eric Bernstein (1):
  drm/amd/display: Check if registers are available before accessing

Eric Yang (1):
  drm/amd/display: add workaround for 4k video underflow

Joshua Aberback (2):
  drm/amd/display: Fix missing hwss function for dce
  drm/amd/display: Fix for NULL ramp pointer crashing driver

Josip Pavic (1):
  drm/amd/display: Pack DMCU iRAM alignment

Krunoslav Kovac (1):
  drm/amd/display: Check for NULL when creating gamma struct

Leo Li (1):
  Revert "drm/amd/display: Signal hw_done() after waiting for
flip_done()"

Martin Tsai (1):
  drm/amd/display: Redefine DMCU_SCRATCH to identify DMCU state

Nicholas Kazlauskas (1):
  drm/amd/display: Fix disabled cursor on top screen edge

Roman Li (1):
  drm/amd/display: fix warning on raven hotplug

Steven Chiu (3):
  drm/amd/display: 3.2.12
  drm/amd/display: 3.2.13
  drm/amd/display: 3.2.14

Tony Cheng (1):
  drm/amd/display: refactor reg_update

abdoulaye berthe (1):
  drm/amd/display: fix CTS 4.2.2.8

hersen wu (1):
  drm/amd/display: dal-pplib interface refactor dal part

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  10 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c|  84 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c   |  57 ++
 drivers/gpu/drm/amd/display/dc/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c   |  13 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c  | 161 +---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   | 111 ++-
 drivers/gpu/drm/amd/display/dc/core/dc_surface.c   |   9 +-
 drivers/gpu/drm/amd/display/dc/dc.h|   3 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h   |  13 +-
 drivers/gpu/drm/amd/display/dc/dc_helper.c |  36 +-
 drivers/gpu/drm/amd/display/dc/dc_types.h  |   1 -
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c   | 647 +++
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.h   |  30 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c  | 123 +--
 .../drm/amd/display/dc/dce/dce_stream_encoder.c|  65 +-
 .../drm/amd/display/dc/dce100/dce100_resource.c|   2 +-
 .../amd/display/dc/dce110/dce110_hw_sequencer.c|  30 +-
 .../drm/amd/display/dc/dce110/dce110_resource.c|   2 +-
 .../drm/amd/display/dc/dce112/dce112_resource.c|   2 +-
 .../drm/amd/display/dc/dce120/dce120_resource.c|   2 +-
 .../gpu/drm/amd/display/dc/dce80/dce80_resource.c  |   2 +-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c   |   2 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c  |  42 +-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c  |   2 +-
 .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c  |  19 +-
 .../drm/amd/display/dc/dcn10/dcn10_link_encoder.c  |   6 +-
 .../drm/amd/display/dc/dcn10/dcn10_link_encoder.h  |   2 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c  |  55 +-
 .../amd/display/dc/dcn10/dcn10_stream_encoder.c|  68 +-
 drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c | 606 --
 drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h |  86 --
 .../amd/display/dc/i2caux/dce100/i2caux_dce100.c   | 106 ---
 .../amd/display/dc/i2caux/dce100/i2caux_dce100.h   |  32 -
 .../display/dc/i2caux/dce110/aux_engine_dce110.c   | 505 
 .../display/dc/i2caux/dce110/aux_engine_dce110.h   |  78 --
 .../dc/i2caux/dce110/i2c_hw_engine_dce110.h| 218 -
 .../dc/i2caux/dce110/i2c_sw_engine_dce110.c| 160 
 .../dc/i2caux/dce110/i2c_sw_engine_dce110.h|  43 -
 .../amd/display/dc/i2caux/dce110/i2caux_dce110.c   | 329 
 .../amd/display/dc/i2caux/dce110/i2caux_dce110.h   |  54 --
 .../amd/display/dc/i2caux/dce120/i2caux_dce120.c   | 120 ---
 .../amd/display/dc/i2caux/dce120/i2caux_dce120.h   |  32 -
 .../display/dc/i2caux/dce80/i2c_hw_engine_dce80.c  | 875 -
 .../display/dc/i2caux/dce80/i2c_hw_engine_dce80.h  |  54 --
 .../display/dc/i2caux/dce80/i2c_sw_engine_dce80.h  |  43 -
 .../drm/amd/display/dc/i2caux/dce80/i2caux_dce80.c | 284 ---
 .../drm/amd/display/dc/i2caux/dce80/i2caux_dce80.h |  38 -
 .../drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c | 120 ---
 .../drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.h |  32 -
 .../display/dc/i2caux/diagnostics/i2caux_diag.c|  97 ---
 

[PATCH 18/25] drm/amd/display: fix warning on raven hotplug

2019-01-08 Thread sunpeng.li
From: Roman Li 

[Why]
Hotplug on raven results in REG_WAIT_TIMEOUT warning
due to failing attempt to lock disabled otg for the hubp
interdependent pipes programming.

[How]
Don't setup pipe interdependencies for disabled otg.
Also removed the unnecessary duplicate logic checks.

Signed-off-by: Roman Li 
Reviewed-by: Dmytro Laktyushkin 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 93226fc..814f597 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -2354,29 +2354,22 @@ static void dcn10_apply_ctx_for_surface(

top_pipe_to_program->plane_state->update_flags.bits.full_update)
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = 
>res_ctx.pipe_ctx[i];
-
+   tg = pipe_ctx->stream_res.tg;
/* Skip inactive pipes and ones already updated */
if (!pipe_ctx->stream || pipe_ctx->stream == stream
-   || !pipe_ctx->plane_state)
+   || !pipe_ctx->plane_state
+   || !tg->funcs->is_tg_enabled(tg))
continue;
 
-   
pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
+   tg->funcs->lock(tg);
 

pipe_ctx->plane_res.hubp->funcs->hubp_setup_interdependent(
pipe_ctx->plane_res.hubp,
_ctx->dlg_regs,
_ctx->ttu_regs);
-   }
-
-   for (i = 0; i < dc->res_pool->pipe_count; i++) {
-   struct pipe_ctx *pipe_ctx = >res_ctx.pipe_ctx[i];
 
-   if (!pipe_ctx->stream || pipe_ctx->stream == stream
-   || !pipe_ctx->plane_state)
-   continue;
-
-   dcn10_pipe_control_lock(dc, pipe_ctx, false);
-   }
+   tg->funcs->unlock(tg);
+   }
 
if (num_planes == 0)
false_optc_underflow_wa(dc, stream, tg);
-- 
2.7.4

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


[PATCH 22/25] drm/amd/display: Add new infopacket definition

2019-01-08 Thread sunpeng.li
From: Bayan Zabihiyan 

Modify freesync module to build VTEM infopackets when in HdmiVRR mode

Signed-off-by: Bayan Zabihiyan 
Reviewed-by: Jun Lei 
Acked-by: Leo Li 
---
 .../drm/amd/display/modules/freesync/freesync.c| 94 --
 .../gpu/drm/amd/display/modules/inc/mod_freesync.h |  2 +-
 .../gpu/drm/amd/display/modules/inc/mod_shared.h   |  3 +-
 3 files changed, 92 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index d967ac0..94a84bc 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -461,6 +461,26 @@ bool mod_freesync_get_v_position(struct mod_freesync 
*mod_freesync,
return false;
 }
 
+static void build_vrr_infopacket_header_vtem(enum signal_type signal,
+   struct dc_info_packet *infopacket)
+{
+   // HEADER
+
+   // HB0, HB1, HB2 indicates PacketType VTEMPacket
+   infopacket->hb0 = 0x7F;
+   infopacket->hb1 = 0xC0;
+   infopacket->hb2 = 0x00;
+   /* HB3 Bit Fields
+* Reserved :1 = 0
+* Sync :1 = 0
+* VFR  :1 = 1
+* Ds_Type  :2 = 0
+* End  :1 = 0
+* New  :1 = 0
+*/
+   infopacket->hb3 = 0x20;
+}
+
 static void build_vrr_infopacket_header_v1(enum signal_type signal,
struct dc_info_packet *infopacket,
unsigned int *payload_size)
@@ -559,6 +579,54 @@ static void build_vrr_infopacket_header_v2(enum 
signal_type signal,
}
 }
 
+static void build_vrr_vtem_infopacket_data(const struct dc_stream_state 
*stream,
+   const struct mod_vrr_params *vrr,
+   struct dc_info_packet *infopacket)
+{
+   /* dc_info_packet to VtemPacket Translation of Bit-fields,
+* SB[6]
+* unsigned char VRR_EN:1
+* unsigned char M_CONST   :1
+* unsigned char Reserved2 :2
+* unsigned char FVA_Factor_M1 :4
+* SB[7]
+* unsigned char Base_Vfront   :8
+* SB[8]
+* unsigned char Base_Refresh_Rate_98 :2
+* unsigned char RB   :1
+* unsigned char Reserved3:5
+* SB[9]
+* unsigned char Base_RefreshRate_07  :8
+*/
+   unsigned int fieldRateInHz;
+
+   if (vrr->state == VRR_STATE_ACTIVE_VARIABLE ||
+   vrr->state == VRR_STATE_ACTIVE_FIXED){
+   infopacket->sb[6] |= 0x80; //VRR_EN Bit = 1
+   } else {
+   infopacket->sb[6] &= 0x7F; //VRR_EN Bit = 0
+   }
+
+   if (!stream->timing.vic) {
+   infopacket->sb[7] = stream->timing.v_front_porch;
+
+   /* TODO: In dal2, we check mode flags for a reduced blanking 
timing.
+* Need a way to relay that information to this function.
+* if("ReducedBlanking")
+* {
+*   infopacket->sb[8] |= 0x20; //Set 3rd bit to 1
+* }
+*/
+   fieldRateInHz = (stream->timing.pix_clk_100hz * 100)/
+   (stream->timing.h_total * 
stream->timing.v_total);
+
+   infopacket->sb[8] |= ((fieldRateInHz & 0x300) >> 2);
+   infopacket->sb[9] |= fieldRateInHz & 0xFF;
+
+   }
+   infopacket->valid = true;
+}
+
 static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr,
struct dc_info_packet *infopacket)
 {
@@ -672,6 +740,19 @@ static void build_vrr_infopacket_v2(enum signal_type 
signal,
infopacket->valid = true;
 }
 
+static void build_vrr_infopacket_vtem(const struct dc_stream_state *stream,
+   const struct mod_vrr_params *vrr,
+   struct dc_info_packet *infopacket)
+{
+   //VTEM info packet for HdmiVrr
+
+   //VTEM Packet is structured differently
+   build_vrr_infopacket_header_vtem(stream->signal, infopacket);
+   build_vrr_vtem_infopacket_data(stream, vrr, infopacket);
+
+   infopacket->valid = true;
+}
+
 void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
const struct dc_stream_state *stream,
const struct mod_vrr_params *vrr,
@@ -679,18 +760,21 @@ void mod_freesync_build_vrr_infopacket(struct 
mod_freesync *mod_freesync,
const enum color_transfer_func *app_tf,
struct dc_info_packet *infopacket)
 {
-   /* SPD info packet for FreeSync */
-
-   /* Check if Freesync is supported. Return if false. If true,
+   /* SPD info packet for FreeSync
+* VTEM info packet for HdmiVRR
+* Check if Freesync is supported. Return if false. If true,
 * set the corresponding bit in the info packet
 */
-   if (!vrr->supported || !vrr->send_vsif)
+   if (!vrr->supported || (!vrr->send_info_frame && packet_type != 
PACKET_TYPE_VTEM))

[PATCH 02/25] drm/amd/display: Fix missing hwss function for dce

2019-01-08 Thread sunpeng.li
From: Joshua Aberback 

[Why]
The driver will crash on dce hardware due to a null function pointer.

[How]
- bring back "program_csc_matrix" functionality as "program_output_csc" for
dce110
- dce110 doesn't use the "opp_id" parameter, so use 0 when there's no hubp

Signed-off-by: Joshua Aberback 
Reviewed-by: Anthony Koo 
Acked-by: Jun Lei 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c   |  2 +-
 .../amd/display/dc/dce110/dce110_hw_sequencer.c| 23 ++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index af907d5..c94bc40 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -451,7 +451,7 @@ bool dc_stream_program_csc_matrix(struct dc *dc, struct 
dc_stream_state *stream)
pipes,
stream->output_color_space,
stream->csc_color_matrix.matrix,
-   pipes->plane_res.hubp->opp_id);
+   pipes->plane_res.hubp ? 
pipes->plane_res.hubp->opp_id : 0);
ret = true;
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 8e961e6..602a41d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -2616,6 +2616,28 @@ static void dce110_wait_for_mpcc_disconnect(
/* do nothing*/
 }
 
+static void program_output_csc(struct dc *dc,
+   struct pipe_ctx *pipe_ctx,
+   enum dc_color_space colorspace,
+   uint16_t *matrix,
+   int opp_id)
+{
+   int i;
+   struct out_csc_color_matrix tbl_entry;
+
+   if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
+   enum dc_color_space color_space = 
pipe_ctx->stream->output_color_space;
+
+   for (i = 0; i < 12; i++)
+   tbl_entry.regval[i] = 
pipe_ctx->stream->csc_color_matrix.matrix[i];
+
+   tbl_entry.color_space = color_space;
+
+   pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
+   pipe_ctx->plane_res.xfm, _entry);
+   }
+}
+
 void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
 {
struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
@@ -2666,6 +2688,7 @@ void dce110_set_cursor_attribute(struct pipe_ctx 
*pipe_ctx)
 
 static const struct hw_sequencer_funcs dce110_funcs = {
.program_gamut_remap = program_gamut_remap,
+   .program_output_csc = program_output_csc,
.init_hw = init_hw,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
-- 
2.7.4

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


[PATCH 17/25] drm/amd/display: dal-pplib interface refactor dal part

2019-01-08 Thread sunpeng.li
From: hersen wu 

[WHY] clarify dal input parameters to pplib interface, remove
un-used parameters. dal knows exactly which parameters needed
and their effects at pplib and smu sides.

current dal sequence for dcn1_update_clock to pplib:

1.smu10_display_clock_voltage_request for dcefclk
2.smu10_display_clock_voltage_request for fclk
3.phm_store_dal_configuration_data {
   set_min_deep_sleep_dcfclk
   set_active_display_count
   store_cc6_data --- this data never be referenced

new sequence will be:

1. set_display_count  --- need add new pplib interface
2. set_min_deep_sleep_dcfclk -- new pplib interface
3. set_hard_min_dcfclk_by_freq
4. set_hard_min_fclk_by_freq

after this code refactor, smu10_display_clock_voltage_request,
phm_store_dal_configuration_data will not be needed for rv.

Signed-off-by: hersen wu 
Reviewed-by: Harry Wentland 
Acked-by: Leo Li 
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c   | 57 ++
 1 file changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index 9d2d698..e8e9eeb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -559,6 +559,58 @@ void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
pp_funcs->notify_smu_enable_pwe(pp_handle);
 }
 
+void pp_rv_set_active_display_count(struct pp_smu *pp, int count)
+{
+   const struct dc_context *ctx = pp->dm;
+   struct amdgpu_device *adev = ctx->driver_context;
+   void *pp_handle = adev->powerplay.pp_handle;
+   const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+   if (!pp_funcs || !pp_funcs->set_active_display_count)
+   return;
+
+   pp_funcs->set_active_display_count(pp_handle, count);
+}
+
+void pp_rv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int clock)
+{
+   const struct dc_context *ctx = pp->dm;
+   struct amdgpu_device *adev = ctx->driver_context;
+   void *pp_handle = adev->powerplay.pp_handle;
+   const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+   if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk)
+   return;
+
+   pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, clock);
+}
+
+void pp_rv_set_hard_min_dcefclk_by_freq(struct pp_smu *pp, int clock)
+{
+   const struct dc_context *ctx = pp->dm;
+   struct amdgpu_device *adev = ctx->driver_context;
+   void *pp_handle = adev->powerplay.pp_handle;
+   const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+   if (!pp_funcs || !pp_funcs->set_hard_min_dcefclk_by_freq)
+   return;
+
+   pp_funcs->set_hard_min_dcefclk_by_freq(pp_handle, clock);
+}
+
+void pp_rv_set_hard_min_fclk_by_freq(struct pp_smu *pp, int mhz)
+{
+   const struct dc_context *ctx = pp->dm;
+   struct amdgpu_device *adev = ctx->driver_context;
+   void *pp_handle = adev->powerplay.pp_handle;
+   const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+   if (!pp_funcs || !pp_funcs->set_hard_min_fclk_by_freq)
+   return;
+
+   pp_funcs->set_hard_min_fclk_by_freq(pp_handle, mhz);
+}
+
 void dm_pp_get_funcs_rv(
struct dc_context *ctx,
struct pp_smu_funcs_rv *funcs)
@@ -567,4 +619,9 @@ void dm_pp_get_funcs_rv(
funcs->set_display_requirement = pp_rv_set_display_requirement;
funcs->set_wm_ranges = pp_rv_set_wm_ranges;
funcs->set_pme_wa_enable = pp_rv_set_pme_wa_enable;
+   funcs->set_display_count = pp_rv_set_active_display_count;
+   funcs->set_min_deep_sleep_dcfclk = pp_rv_set_min_deep_sleep_dcfclk;
+   funcs->set_hard_min_dcfclk_by_freq = pp_rv_set_hard_min_dcefclk_by_freq;
+   funcs->set_hard_min_fclk_by_freq = pp_rv_set_hard_min_fclk_by_freq;
 }
+
-- 
2.7.4

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


[PATCH 11/25] drm/amd/display: Fix disabled cursor on top screen edge

2019-01-08 Thread sunpeng.li
From: Nicholas Kazlauskas 

[Why]
The cursor vanishes when touching the top of edge of the screen for
Raven on Linux.

This occurs because the cursor height is not taken into account when
deciding to disable the cursor.

[How]
Factor in the cursor height into the cursor calculations - and mimic
the existing x position calculations.

Fixes: 94a4ffd1d40b ("drm/amd/display: fix PIP bugs on Dal3")

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c  | 2 +-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index dcb3c55..cd1ebe5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -463,7 +463,7 @@ void dpp1_set_cursor_position(
if (src_y_offset >= (int)param->viewport.height)
cur_en = 0;  /* not visible beyond bottom edge*/
 
-   if (src_y_offset < 0)
+   if (src_y_offset + (int)height <= 0)
cur_en = 0;  /* not visible beyond top edge*/
 
REG_UPDATE(CURSOR0_CONTROL,
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 e24ea61..fae6247 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -1140,7 +1140,7 @@ void hubp1_cursor_set_position(
if (src_y_offset >= (int)param->viewport.height)
cur_en = 0;  /* not visible beyond bottom edge*/
 
-   if (src_y_offset < 0) //+ (int)hubp->curs_attr.height
+   if (src_y_offset + (int)hubp->curs_attr.height <= 0)
cur_en = 0;  /* not visible beyond top edge*/
 
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
-- 
2.7.4

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


[PATCH 09/25] drm/amd/display: Fix for NULL ramp pointer crashing driver

2019-01-08 Thread sunpeng.li
From: Joshua Aberback 

[Why]
In certain scenarios the ramp parameter come in as NULL, which crashes
because this function doesn't guard properly in the early return.

[How]
- parameter mapUserRamp should be the guard (false means no ramp)
- remove checking ramp in early return

Signed-off-by: Joshua Aberback 
Reviewed-by: Sivapiriyan Kumarasamy 
Acked-by: Eryk Brol 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index beb7bda..4cee084 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -1772,8 +1772,7 @@ bool mod_color_calculate_degamma_params(struct 
dc_transfer_func *input_tf,
/* we can use hardcoded curve for plain SRGB TF */
if (input_tf->type == TF_TYPE_PREDEFINED &&
input_tf->tf == TRANSFER_FUNCTION_SRGB &&
-   (!mapUserRamp &&
-   (ramp->type == GAMMA_RGB_256 || ramp->num_entries == 
0)))
+   !mapUserRamp)
return true;
 
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
-- 
2.7.4

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


[PATCH 08/25] drm/amd/display: Redefine DMCU_SCRATCH to identify DMCU state

2019-01-08 Thread sunpeng.li
From: Martin Tsai 

[why]
To resume system before entering S0i3 completely will cause PSP not
reload DMCU FW since there is not HW power state change.
In this case, driver cannot get correct DMCU version from IRAM
since driver override it and DMCU didn't reload to update it.
It makes driver return false in dcn10_dmcu_init().

[how]
1.To redefine DMCU_SCRATCH to identify different DMCU state.
2.To reserve IRAM 0xF0~0xFF write by DMCU only.
3.To remove dcn10_get_dmcu_state

Signed-off-by: Martin Tsai 
Reviewed-by: Anthony Koo 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c  | 123 +++--
 drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h   |  10 +-
 .../drm/amd/display/modules/power/power_helpers.c  |   3 +-
 3 files changed, 52 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index dea40b3..e927c89 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -51,7 +51,6 @@
 #define PSR_SET_WAITLOOP 0x31
 #define MCP_INIT_DMCU 0x88
 #define MCP_INIT_IRAM 0x89
-#define MCP_DMCU_VERSION 0x90
 #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK   0x0001L
 
 static bool dce_dmcu_init(struct dmcu *dmcu)
@@ -317,38 +316,11 @@ static void dce_get_psr_wait_loop(
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
-static void dcn10_get_dmcu_state(struct dmcu *dmcu)
-{
-   struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
-   uint32_t dmcu_state_offset = 0xf6;
-
-   /* Enable write access to IRAM */
-   REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
-   IRAM_HOST_ACCESS_EN, 1,
-   IRAM_RD_ADDR_AUTO_INC, 1);
-
-   REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);
-
-   /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */
-   REG_WRITE(DMCU_IRAM_RD_CTRL, dmcu_state_offset);
-
-   /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
-   dmcu->dmcu_state = REG_READ(DMCU_IRAM_RD_DATA);
-
-   /* Disable write access to IRAM to allow dynamic sleep state */
-   REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
-   IRAM_HOST_ACCESS_EN, 0,
-   IRAM_RD_ADDR_AUTO_INC, 0);
-}
-
 static void dcn10_get_dmcu_version(struct dmcu *dmcu)
 {
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
uint32_t dmcu_version_offset = 0xf1;
 
-   /* Clear scratch */
-   REG_WRITE(DC_DMCU_SCRATCH, 0);
-
/* Enable write access to IRAM */
REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
IRAM_HOST_ACCESS_EN, 1,
@@ -368,76 +340,65 @@ static void dcn10_get_dmcu_version(struct dmcu *dmcu)
REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
IRAM_HOST_ACCESS_EN, 0,
IRAM_RD_ADDR_AUTO_INC, 0);
-
-   /* Send MCP command message to DMCU to get version reply from FW.
-* We expect this version should match the one in IRAM, otherwise
-* something is wrong with DMCU and we should fail and disable UC.
-*/
-   REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
-
-   /* Set command to get DMCU version from microcontroller */
-   REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
-   MCP_DMCU_VERSION);
-
-   /* Notify microcontroller of new command */
-   REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
-
-   /* Ensure command has been executed before continuing */
-   REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
-
-   /* Somehow version does not match, so fail and return version 0 */
-   if (dmcu->dmcu_version.interface_version != REG_READ(DC_DMCU_SCRATCH))
-   dmcu->dmcu_version.interface_version = 0;
 }
 
 static bool dcn10_dmcu_init(struct dmcu *dmcu)
 {
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
+   bool status = false;
 
-   /* DMCU FW should populate the scratch register if running */
-   if (REG_READ(DC_DMCU_SCRATCH) == 0)
-   return false;
-
-   /* Check state is uninitialized */
-   dcn10_get_dmcu_state(dmcu);
-
-   /* If microcontroller is already initialized, do nothing */
-   if (dmcu->dmcu_state == DMCU_RUNNING)
-   return true;
-
-   /* Retrieve and cache the DMCU firmware version. */
-   dcn10_get_dmcu_version(dmcu);
-
-   /* Check interface version to confirm firmware is loaded and running */
-   if (dmcu->dmcu_version.interface_version == 0)
-   return false;
+   /*  Definition of DC_DMCU_SCRATCH
+*  0 : firmare not loaded
+*  1 : PSP load DMCU FW but not initialized
+*  2 : Firmware already initialized
+*/
+   dmcu->dmcu_state = REG_READ(DC_DMCU_SCRATCH);
 
-   /* Wait until microcontroller is ready to process interrupt */
-   REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 

[PATCH 04/25] drm/amd/display: fix CTS 4.2.2.8

2019-01-08 Thread sunpeng.li
From: abdoulaye berthe 

[Why]
1-Test equipment does not reset test automation flag after completing
current test causing the next test to fail.
2.When test request is empty, we shouldn't ack the test.

[How]
1-Driver should always clear test equipment automation test request
when request is completed.
2-Driver should clear test equipement test automation if driver does
not complete the request.

Signed-off-by: abdoulaye berthe 
Reviewed-by: Wenjing Liu 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 568fdc9..cf93627 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2002,11 +2002,7 @@ static void handle_automated_test(struct dc_link *link)
dp_test_send_phy_test_pattern(link);
test_response.bits.ACK = 1;
}
-   if (!test_request.raw)
-   /* no requests, revert all test signals
-* TODO: revert all test signals
-*/
-   test_response.bits.ACK = 1;
+
/* send request acknowledgment */
if (test_response.bits.ACK)
core_link_write_dpcd(
-- 
2.7.4

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


[PATCH 21/25] drm/amd/display: Rename configure_encoder to enc1_configure_encoder

2019-01-08 Thread sunpeng.li
From: Dmytro Laktyushkin 

Signed-off-by: Dmytro Laktyushkin 
Reviewed-by: Charlene Liu 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 6 +++---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
index af0bcff..771449f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -440,7 +440,7 @@ static uint8_t get_frontend_source(
}
 }
 
-void configure_encoder(
+void enc1_configure_encoder(
struct dcn10_link_encoder *enc10,
const struct dc_link_settings *link_settings)
 {
@@ -910,7 +910,7 @@ void dcn10_link_encoder_enable_dp_output(
 * but it's not passed to asic_control.
 * We need to set number of lanes manually.
 */
-   configure_encoder(enc10, link_settings);
+   enc1_configure_encoder(enc10, link_settings);
 
cntl.action = TRANSMITTER_CONTROL_ENABLE;
cntl.engine_id = enc->preferred_engine;
@@ -949,7 +949,7 @@ void dcn10_link_encoder_enable_dp_mst_output(
 * but it's not passed to asic_control.
 * We need to set number of lanes manually.
 */
-   configure_encoder(enc10, link_settings);
+   enc1_configure_encoder(enc10, link_settings);
 
cntl.action = TRANSMITTER_CONTROL_ENABLE;
cntl.engine_id = ENGINE_ID_UNKNOWN;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
index 49ead12..670b46e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -271,7 +271,7 @@ void dcn10_link_encoder_setup(
struct link_encoder *enc,
enum signal_type signal);
 
-void configure_encoder(
+void enc1_configure_encoder(
struct dcn10_link_encoder *enc10,
const struct dc_link_settings *link_settings);
 
-- 
2.7.4

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


[PATCH 05/25] Revert "drm/amd/display: Signal hw_done() after waiting for flip_done()"

2019-01-08 Thread sunpeng.li
From: Leo Li 

This reverts commit 717276b9256f5d97b43e53adca1670cee2c45db2.

The reverted patch was a workaround that addressed an issue fixed by:
4364bcb2cd21 ("drm: Get ref on CRTC commit object when waiting for
flip_done")

Signed-off-by: Leo Li 
Reviewed-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++
 1 file changed, 2 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 70cd8bc..3ede2d1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5346,18 +5346,12 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
}
spin_unlock_irqrestore(>ddev->event_lock, flags);
 
+   /* Signal HW programming completion */
+   drm_atomic_helper_commit_hw_done(state);
 
if (wait_for_vblank)
drm_atomic_helper_wait_for_flip_done(dev, state);
 
-   /*
-* FIXME:
-* Delay hw_done() until flip_done() is signaled. This is to block
-* another commit from freeing the CRTC state while we're still
-* waiting on flip_done.
-*/
-   drm_atomic_helper_commit_hw_done(state);
-
drm_atomic_helper_cleanup_planes(dev, state);
 
/*
-- 
2.7.4

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


[PATCH 07/25] drm/amd/display: fix PME notification not working in RV desktop

2019-01-08 Thread sunpeng.li
From: Charlene Liu 

[Why]
PPLIB not receive the PME when unplug.

Signed-off-by: Charlene Liu 
Reviewed-by: Chris Park 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 602a41d..144a1c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -997,7 +997,7 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
 

pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
 
-   if (num_audio == 1 && pp_smu != NULL && 
pp_smu->set_pme_wa_enable != NULL)
+   if (num_audio >= 1 && pp_smu != NULL && 
pp_smu->set_pme_wa_enable != NULL)
/*this is the first audio. apply the PME w/a in order 
to wake AZ from D3*/
pp_smu->set_pme_wa_enable(_smu->pp_smu);
/* un-mute audio */
@@ -1014,6 +1014,8 @@ void dce110_disable_audio_stream(struct pipe_ctx 
*pipe_ctx, int option)
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, true);
if (pipe_ctx->stream_res.audio) {
+   struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu;
+
if (option != KEEP_ACQUIRED_RESOURCE ||
!dc->debug.az_endpoint_mute_only) {
/*only disalbe az_endpoint if power down or free*/
@@ -1033,6 +1035,9 @@ void dce110_disable_audio_stream(struct pipe_ctx 
*pipe_ctx, int option)
update_audio_usage(>current_state->res_ctx, 
dc->res_pool, pipe_ctx->stream_res.audio, false);
pipe_ctx->stream_res.audio = NULL;
}
+   if (pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL)
+   /*this is the first audio. apply the PME w/a in order 
to wake AZ from D3*/
+   pp_smu->set_pme_wa_enable(_smu->pp_smu);
 
/* TODO: notify audio driver for if audio modes list changed
 * add audio mode list change flag */
-- 
2.7.4

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


[PATCH 10/25] drm/amd/display: Set link rate set if eDP ver >= 1.4.

2019-01-08 Thread sunpeng.li
From: Derek Lai 

[Why]
If eDP ver >= 1.4,
the Source device must use LINK_RATE_SET.

[How]
Get LINK_RATE_SET by reading DPCD 10h-1fh,
then write DPCD 00115h before link training.

Signed-off-by: Derek Lai 
Reviewed-by: Tony Cheng 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 105 ++-
 drivers/gpu/drm/amd/display/dc/dc.h  |   1 +
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h |  13 +--
 3 files changed, 111 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index cf93627..431805c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -117,6 +117,13 @@ static void dpcd_set_link_settings(
core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
, sizeof(downspread));
 
+   if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
+   (link->dpcd_caps.link_rate_set >= 1 &&
+   link->dpcd_caps.link_rate_set <= 8)) {
+   core_link_write_dpcd(link, DP_LINK_RATE_SET,
+   >dpcd_caps.link_rate_set, 1);
+   }
+
DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x\n %x spread = 
%x\n",
__func__,
DP_LINK_BW_SET,
@@ -2489,13 +2496,105 @@ bool detect_dp_sink_caps(struct dc_link *link)
/* TODO save sink caps in link->sink */
 }
 
+enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
+{
+   enum dc_link_rate link_rate;
+   // LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. 
Do the translation.
+   switch (link_rate_in_khz) {
+   case 162:
+   link_rate = LINK_RATE_LOW;  // Rate_1 (RBR) 
- 1.62 Gbps/Lane
+   break;
+   case 216:
+   link_rate = LINK_RATE_RATE_2;   // Rate_2   
- 2.16 Gbps/Lane
+   break;
+   case 243:
+   link_rate = LINK_RATE_RATE_3;   // Rate_3   
- 2.43 Gbps/Lane
+   break;
+   case 270:
+   link_rate = LINK_RATE_HIGH; // Rate_4 (HBR) 
- 2.70 Gbps/Lane
+   break;
+   case 324:
+   link_rate = LINK_RATE_RBR2; // Rate_5 (RBR2)
- 3.24 Gbps/Lane
+   break;
+   case 432:
+   link_rate = LINK_RATE_RATE_6;   // Rate_6   
- 4.32 Gbps/Lane
+   break;
+   case 540:
+   link_rate = LINK_RATE_HIGH2;// Rate_7 (HBR2)- 5.40 
Gbps/Lane
+   break;
+   case 810:
+   link_rate = LINK_RATE_HIGH3;// Rate_8 (HBR3)- 8.10 
Gbps/Lane
+   break;
+   default:
+   link_rate = LINK_RATE_UNKNOWN;
+   break;
+   }
+   return link_rate;
+}
+
 void detect_edp_sink_caps(struct dc_link *link)
 {
-   retrieve_link_cap(link);
+   uint8_t supported_link_rates[16] = {0};
+   uint32_t entry;
+   uint32_t link_rate_in_khz;
+   enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
+   uint8_t link_rate_set = 0;
 
-   if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
-   link->reported_link_cap.link_rate = LINK_RATE_HIGH2;
+   retrieve_link_cap(link);
 
+   if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
+   // Read DPCD 00010h - 0001Fh 16 bytes at one shot
+   core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
+   supported_link_rates, 
sizeof(supported_link_rates));
+
+   link->dpcd_caps.link_rate_set = 0;
+   for (entry = 0; entry < 16; entry += 2) {
+   // DPCD register reports per-lane link rate = 16-bit 
link rate capability
+   // value X 200 kHz. Need multipler to find link rate in 
kHz.
+   link_rate_in_khz = (supported_link_rates[entry+1] * 
0x100 +
+   
supported_link_rates[entry]) * 200;
+
+   if (link_rate_in_khz != 0) {
+   link_rate = 
linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
+   if (link->reported_link_cap.link_rate < 
link_rate) {
+   link->reported_link_cap.link_rate = 
link_rate;
+
+   switch (link_rate) {
+   case LINK_RATE_LOW:
+   link_rate_set = 1;
+   break;
+   case LINK_RATE_RATE_2:
+   link_rate_set = 2;
+   break;
+ 

[PATCH 01/25] drm/amd/display: 3.2.12

2019-01-08 Thread sunpeng.li
From: Steven Chiu 

Signed-off-by: Steven Chiu 
Reviewed-by: Yongqiang Sun 
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 ee70540..f80f52e 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.11"
+#define DC_VER "3.2.12"
 
 #define MAX_SURFACES 3
 #define MAX_STREAMS 6
-- 
2.7.4

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


[PATCH 06/25] drm/amd/display: refactor reg_update

2019-01-08 Thread sunpeng.li
From: Tony Cheng 

[why]
separate register access from logic to allow us abstract register sequences

[how]
consolidate mask and value first then apply to register.

Signed-off-by: Tony Cheng 
Reviewed-by: Tony Cheng 
Acked-by: Leo Li 
---
 drivers/gpu/drm/amd/display/dc/dc_helper.c | 36 ++
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c 
b/drivers/gpu/drm/amd/display/dc/dc_helper.c
index 4842d23..597d383 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c
@@ -29,31 +29,59 @@
 #include "dm_services.h"
 #include 
 
+struct dc_reg_value_masks {
+   uint32_t value;
+   uint32_t mask;
+};
+
+struct dc_reg_sequence {
+   uint32_t addr;
+   struct dc_reg_value_masks value_masks;
+};
+
+static inline void set_reg_field_value_masks(
+   struct dc_reg_value_masks *field_value_mask,
+   uint32_t value,
+   uint32_t mask,
+   uint8_t shift)
+{
+   ASSERT(mask != 0);
+
+   field_value_mask->value = (field_value_mask->value & ~mask) | (mask & 
(value << shift));
+   field_value_mask->mask = field_value_mask->mask | mask;
+}
+
 uint32_t generic_reg_update_ex(const struct dc_context *ctx,
uint32_t addr, uint32_t reg_val, int n,
uint8_t shift1, uint32_t mask1, uint32_t field_value1,
...)
 {
+   struct dc_reg_value_masks field_value_mask = {0};
uint32_t shift, mask, field_value;
int i = 1;
 
va_list ap;
va_start(ap, field_value1);
 
-   reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
+   /* gather all bits value/mask getting updated in this register */
+   set_reg_field_value_masks(_value_mask,
+   field_value1, mask1, shift1);
 
while (i < n) {
shift = va_arg(ap, uint32_t);
mask = va_arg(ap, uint32_t);
field_value = va_arg(ap, uint32_t);
 
-   reg_val = set_reg_field_value_ex(reg_val, field_value, mask, 
shift);
+   set_reg_field_value_masks(_value_mask,
+   field_value, mask, shift);
i++;
}
-
-   dm_write_reg(ctx, addr, reg_val);
va_end(ap);
 
+
+   /* mmio write directly */
+   reg_val = (reg_val & ~field_value_mask.mask) | field_value_mask.value;
+   dm_write_reg(ctx, addr, reg_val);
return reg_val;
 }
 
-- 
2.7.4

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


Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3

2019-01-08 Thread Alex Deucher
On Tue, Jan 8, 2019 at 6:28 AM Russell, Kent  wrote:
>
> Add a sysfs file that reports the number of bytes transmitted and
> received in the last second. This can be used to approximate the PCIe
> bandwidth usage over the last second.
>
> v2: Clarify use of mps as estimation of bandwidth
> v3: Don't make the file on APUs
>
> Signed-off-by: Kent Russell 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  4 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 +
>  drivers/gpu/drm/amd/amdgpu/cik.c   | 41 +++
>  drivers/gpu/drm/amd/amdgpu/si.c| 41 +++
>  drivers/gpu/drm/amd/amdgpu/soc15.c | 44 
> ++
>  drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++
>  6 files changed, 209 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index e1b2c64..512b124 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs {
> bool (*need_full_reset)(struct amdgpu_device *adev);
> /* initialize doorbell layout for specific asic*/
> void (*init_doorbell_index)(struct amdgpu_device *adev);
> +   /* PCIe bandwidth usage */
> +   void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0,
> +  uint64_t *count1);
>  };
>
>  /*
> @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
>  #define amdgpu_asic_invalidate_hdp(adev, r) 
> (adev)->asic_funcs->invalidate_hdp((adev), (r))
>  #define amdgpu_asic_need_full_reset(adev) 
> (adev)->asic_funcs->need_full_reset((adev))
>  #define amdgpu_asic_init_doorbell_index(adev) 
> (adev)->asic_funcs->init_doorbell_index((adev))
> +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) 
> ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
>
>  /* Common functions */
>  bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 6896dec..d2b29fd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device 
> *dev,
> return snprintf(buf, PAGE_SIZE, "%d\n", value);
>  }
>
> +/**
> + * DOC: pcie_bw
> + *
> + * The amdgpu driver provides a sysfs API for reading how much data
> + * has been sent and received by the GPU in the last second through PCIe.
> + * The file pcie_bw is used for this.
> + * The Perf counters calculate this and return the number of sent and 
> received
> + * messages, which we multiply by the maxsize of our PCIe packets (mps).
> + * Note that it is not possible to easily and quickly obtain the size of each
> + * packet transmitted, so we use the max payload size (mps) to estimate the
> + * PCIe bandwidth usage
> + */
> +static ssize_t amdgpu_get_pcie_bw(struct device *dev,
> +   struct device_attribute *attr,
> +   char *buf)
> +{
> +   struct drm_device *ddev = dev_get_drvdata(dev);
> +   struct amdgpu_device *adev = ddev->dev_private;
> +   uint64_t mps = pcie_get_mps(adev->pdev);
> +   uint64_t count0, count1;
> +
> +   amdgpu_asic_get_pcie_usage(adev, , );
> +   return snprintf(buf, PAGE_SIZE,
> +   "Bytes received: %llu\nBytes sent: %llu\n",
> +   count0 * mps, count1 * mps);
> +}
> +
>  static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, 
> amdgpu_set_dpm_state);
>  static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
>amdgpu_get_dpm_forced_performance_level,
> @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
> amdgpu_set_pp_od_clk_voltage);
>  static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
> amdgpu_get_busy_percent, NULL);
> +static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL);
>
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
>   struct device_attribute *attr,
> @@ -2108,6 +2136,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
> "gpu_busy_level\n");
> return ret;
> }
> +   /* PCIe Perf counters won't work on APU nodes */
> +   if (adev->flags & !AMD_IS_APU) {
> +   ret = device_create_file(adev->dev, _attr_pcie_bw);
> +   if (ret) {
> +   DRM_ERROR("failed to create device file pcie_bw\n");
> +   return ret;
> +   }
> +   }
> ret = amdgpu_debugfs_pm_init(adev);
> if (ret) {
> DRM_ERROR("Failed to register debugfs file for dpm!\n");
> @@ -2147,6 +2183,8 @@ void amdgpu_pm_sysfs_fini(struct 

Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3

2019-01-08 Thread Alex Deucher
On Tue, Jan 8, 2019 at 11:02 AM Kuehling, Felix  wrote:
>
>
> On 2019-01-08 6:28 a.m., Russell, Kent wrote:
> > Add a sysfs file that reports the number of bytes transmitted and
> > received in the last second. This can be used to approximate the PCIe
> > bandwidth usage over the last second.
> >
> > v2: Clarify use of mps as estimation of bandwidth
>
> I think you only updated the code comment, but not the output in sysfs.
>
> More generally, most amdgpu sysfs files report a single value, or a set
> of values separated by spaces. That makes it easier to parse by external
> tools. It's also supposed to be a stable API. They don't usually include
> human readable text such as "bytes received:". It would be up to a tool
> such as rocm-smi to turn this into human-readable text.
>
> In keeping with that convention I'd suggest reporting the PCIe bandwidth
> as three numbers:
>
>   
>
> Then let the tool calculate the bytes estimate with the appropriate
> warnings about how accurate that is.
>
> Alex does this match your understanding regarding sysfs conventions?

Yes, agreed.

Alex

>
> Regards,
>   Felix
>
> > v3: Don't make the file on APUs
> >
> > Signed-off-by: Kent Russell 
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  4 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 +
> >  drivers/gpu/drm/amd/amdgpu/cik.c   | 41 +++
> >  drivers/gpu/drm/amd/amdgpu/si.c| 41 +++
> >  drivers/gpu/drm/amd/amdgpu/soc15.c | 44 
> > ++
> >  drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++
> >  6 files changed, 209 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > index e1b2c64..512b124 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs {
> >   bool (*need_full_reset)(struct amdgpu_device *adev);
> >   /* initialize doorbell layout for specific asic*/
> >   void (*init_doorbell_index)(struct amdgpu_device *adev);
> > + /* PCIe bandwidth usage */
> > + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0,
> > +uint64_t *count1);
> >  };
> >
> >  /*
> > @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
> >  #define amdgpu_asic_invalidate_hdp(adev, r) 
> > (adev)->asic_funcs->invalidate_hdp((adev), (r))
> >  #define amdgpu_asic_need_full_reset(adev) 
> > (adev)->asic_funcs->need_full_reset((adev))
> >  #define amdgpu_asic_init_doorbell_index(adev) 
> > (adev)->asic_funcs->init_doorbell_index((adev))
> > +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) 
> > ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
> >
> >  /* Common functions */
> >  bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> > index 6896dec..d2b29fd 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> > @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device 
> > *dev,
> >   return snprintf(buf, PAGE_SIZE, "%d\n", value);
> >  }
> >
> > +/**
> > + * DOC: pcie_bw
> > + *
> > + * The amdgpu driver provides a sysfs API for reading how much data
> > + * has been sent and received by the GPU in the last second through PCIe.
> > + * The file pcie_bw is used for this.
> > + * The Perf counters calculate this and return the number of sent and 
> > received
> > + * messages, which we multiply by the maxsize of our PCIe packets (mps).
> > + * Note that it is not possible to easily and quickly obtain the size of 
> > each
> > + * packet transmitted, so we use the max payload size (mps) to estimate the
> > + * PCIe bandwidth usage
> > + */
> > +static ssize_t amdgpu_get_pcie_bw(struct device *dev,
> > + struct device_attribute *attr,
> > + char *buf)
> > +{
> > + struct drm_device *ddev = dev_get_drvdata(dev);
> > + struct amdgpu_device *adev = ddev->dev_private;
> > + uint64_t mps = pcie_get_mps(adev->pdev);
> > + uint64_t count0, count1;
> > +
> > + amdgpu_asic_get_pcie_usage(adev, , );
> > + return snprintf(buf, PAGE_SIZE,
> > + "Bytes received: %llu\nBytes sent: %llu\n",
> > + count0 * mps, count1 * mps);
> > +}
> > +
> >  static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, 
> > amdgpu_get_dpm_state, amdgpu_set_dpm_state);
> >  static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
> >  amdgpu_get_dpm_forced_performance_level,
> > @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | 
> > S_IWUSR,
> >   amdgpu_set_pp_od_clk_voltage);
> >  static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
> >   

Re: [PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3

2019-01-08 Thread Kuehling, Felix

On 2019-01-08 6:28 a.m., Russell, Kent wrote:
> Add a sysfs file that reports the number of bytes transmitted and
> received in the last second. This can be used to approximate the PCIe
> bandwidth usage over the last second.
>
> v2: Clarify use of mps as estimation of bandwidth

I think you only updated the code comment, but not the output in sysfs.

More generally, most amdgpu sysfs files report a single value, or a set
of values separated by spaces. That makes it easier to parse by external
tools. It's also supposed to be a stable API. They don't usually include
human readable text such as "bytes received:". It would be up to a tool
such as rocm-smi to turn this into human-readable text.

In keeping with that convention I'd suggest reporting the PCIe bandwidth
as three numbers:

      

Then let the tool calculate the bytes estimate with the appropriate
warnings about how accurate that is.

Alex does this match your understanding regarding sysfs conventions?

Regards,
  Felix

> v3: Don't make the file on APUs
>
> Signed-off-by: Kent Russell 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h|  4 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 +
>  drivers/gpu/drm/amd/amdgpu/cik.c   | 41 +++
>  drivers/gpu/drm/amd/amdgpu/si.c| 41 +++
>  drivers/gpu/drm/amd/amdgpu/soc15.c | 44 
> ++
>  drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++
>  6 files changed, 209 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index e1b2c64..512b124 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -542,6 +542,9 @@ struct amdgpu_asic_funcs {
>   bool (*need_full_reset)(struct amdgpu_device *adev);
>   /* initialize doorbell layout for specific asic*/
>   void (*init_doorbell_index)(struct amdgpu_device *adev);
> + /* PCIe bandwidth usage */
> + void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0,
> +uint64_t *count1);
>  };
>  
>  /*
> @@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
>  #define amdgpu_asic_invalidate_hdp(adev, r) 
> (adev)->asic_funcs->invalidate_hdp((adev), (r))
>  #define amdgpu_asic_need_full_reset(adev) 
> (adev)->asic_funcs->need_full_reset((adev))
>  #define amdgpu_asic_init_doorbell_index(adev) 
> (adev)->asic_funcs->init_doorbell_index((adev))
> +#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) 
> ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
>  
>  /* Common functions */
>  bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 6896dec..d2b29fd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device 
> *dev,
>   return snprintf(buf, PAGE_SIZE, "%d\n", value);
>  }
>  
> +/**
> + * DOC: pcie_bw
> + *
> + * The amdgpu driver provides a sysfs API for reading how much data
> + * has been sent and received by the GPU in the last second through PCIe.
> + * The file pcie_bw is used for this.
> + * The Perf counters calculate this and return the number of sent and 
> received
> + * messages, which we multiply by the maxsize of our PCIe packets (mps).
> + * Note that it is not possible to easily and quickly obtain the size of each
> + * packet transmitted, so we use the max payload size (mps) to estimate the
> + * PCIe bandwidth usage
> + */
> +static ssize_t amdgpu_get_pcie_bw(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct drm_device *ddev = dev_get_drvdata(dev);
> + struct amdgpu_device *adev = ddev->dev_private;
> + uint64_t mps = pcie_get_mps(adev->pdev);
> + uint64_t count0, count1;
> +
> + amdgpu_asic_get_pcie_usage(adev, , );
> + return snprintf(buf, PAGE_SIZE,
> + "Bytes received: %llu\nBytes sent: %llu\n",
> + count0 * mps, count1 * mps);
> +}
> +
>  static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, 
> amdgpu_set_dpm_state);
>  static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
>  amdgpu_get_dpm_forced_performance_level,
> @@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
>   amdgpu_set_pp_od_clk_voltage);
>  static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
>   amdgpu_get_busy_percent, NULL);
> +static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL);
>  
>  static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
> struct device_attribute *attr,
> @@ -2108,6 +2136,14 @@ int amdgpu_pm_sysfs_init(struct 

Re: [PATCH v6 1/2] drm/amd: validate user pitch alignment

2019-01-08 Thread Michel Dänzer
On 2019-01-07 11:51 p.m., Yu Zhao wrote:
> Userspace may request pitch alignment that is not supported by GPU.
> Some requests 32, but GPU ignores it and uses default 64 when cpp is
> 4. If GEM object is allocated based on the smaller alignment, GPU
> DMA will go out of bound.
> 
> Cc: sta...@vger.kernel.org # v4.2+
> Signed-off-by: Yu Zhao 

Both patches applied to amd-staging-drm-next (should land in 5.0), thanks!


-- 
Earthling Michel Dänzer   |   http://www.amd.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: Adaptive Sync/VRR not working in multi-head with a non-freesync monitor

2019-01-08 Thread Michel Dänzer
On 2019-01-08 1:41 p.m., Ilya Trukhanov wrote:
> Tried Unigine Valley with bspwm and Plasma, Freesync does not get
> engaged when second monitor (without Freesync support) is in use.
> If I turn it off with e.g.
> 
> $ xrandr --output HDMI-A-0 --off
> 
> Freesync immediately starts working. Once I turn the monitor back on,
> Freesync is gone.
> 
> 
> Looking through one of the patches at
> https://gitlab.freedesktop.org/xorg/driver/xf86-video-amdgpu/merge_requests/5
> I found this:
> 
>> Per-CRTC support is gone for enabling variable refresh.
>> A window must cover the entire X screen in order to flip
>> so every CRTC must be enabled or disabled at the same time.
> 
> If I understood correctly, in case of multi-head, a window must span
> across all monitors, with all monitors having Freesync support.
> Therefore, my setup won't work in this case. However, it *does* work on
> Windows (albeit only one monitor has Freesync working, obviously).
> 
> Am I missing something obvious?
> Or is this some kind of X design limitation?

Yes, it is. Variable refresh rate can only work with page flipping, and
page flipping can only be used in Xorg when the application window spans
the whole virtual desktop.


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



signature.asc
Description: OpenPGP digital signature
___
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 VEGA20

2019-01-08 Thread Alex Deucher
On Tue, Jan 8, 2019 at 5:55 AM Tao Zhou  wrote:
>
> Fix CPDMA hang in PRT mode for both of VEGA10 and VEGA20
>
> Change-Id: I0e5e089d2192063c4a04fa6dbd534f25eb0177be
> Signed-off-by: Tao Zhou 
> Tested-by: Yukun.Li 

Acked-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> index 968b127c6c8f..fbca0494f871 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> @@ -113,7 +113,10 @@ static const struct soc15_reg_golden 
> golden_settings_gc_9_0[] =
> SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0x, 
> 0x4a2c0e68),
> 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, 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)
>  };
>
>  static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
> @@ -135,10 +138,7 @@ static const struct soc15_reg_golden 
> golden_settings_gc_9_0_vg10[] =
> SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2, 0x0003, 
> 0x0002),
> SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x000f, 
> 0x01000107),
> SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x1800, 0x0800),
> -   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, mmWD_UTCL1_CNTL, 0x0800, 0x0880)
>  };
>
>  static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] =
> --
> 2.17.1
>
> ___
> 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


Adaptive Sync/VRR not working in multi-head with a non-freesync monitor

2019-01-08 Thread Ilya Trukhanov
Tried Unigine Valley with bspwm and Plasma, Freesync does not get
engaged when second monitor (without Freesync support) is in use.
If I turn it off with e.g.

$ xrandr --output HDMI-A-0 --off

Freesync immediately starts working. Once I turn the monitor back on,
Freesync is gone.


Looking through one of the patches at
https://gitlab.freedesktop.org/xorg/driver/xf86-video-amdgpu/merge_requests/5
I found this:

> Per-CRTC support is gone for enabling variable refresh.
> A window must cover the entire X screen in order to flip
> so every CRTC must be enabled or disabled at the same time.

If I understood correctly, in case of multi-head, a window must span
across all monitors, with all monitors having Freesync support.
Therefore, my setup won't work in this case. However, it *does* work on
Windows (albeit only one monitor has Freesync working, obviously).

Am I missing something obvious?
Or is this some kind of X design limitation?
Are there any possible workarounds to achieve the same functionality as
on Windows?


I would greatly appreciate some clarification on this topic. Thank you!


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


[PATCH] drm/amdgpu: Add sysfs file for PCIe usage v3

2019-01-08 Thread Russell, Kent
Add a sysfs file that reports the number of bytes transmitted and
received in the last second. This can be used to approximate the PCIe
bandwidth usage over the last second.

v2: Clarify use of mps as estimation of bandwidth
v3: Don't make the file on APUs

Signed-off-by: Kent Russell 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 38 +
 drivers/gpu/drm/amd/amdgpu/cik.c   | 41 +++
 drivers/gpu/drm/amd/amdgpu/si.c| 41 +++
 drivers/gpu/drm/amd/amdgpu/soc15.c | 44 ++
 drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++
 6 files changed, 209 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index e1b2c64..512b124 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -542,6 +542,9 @@ struct amdgpu_asic_funcs {
bool (*need_full_reset)(struct amdgpu_device *adev);
/* initialize doorbell layout for specific asic*/
void (*init_doorbell_index)(struct amdgpu_device *adev);
+   /* PCIe bandwidth usage */
+   void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0,
+  uint64_t *count1);
 };
 
 /*
@@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 #define amdgpu_asic_invalidate_hdp(adev, r) 
(adev)->asic_funcs->invalidate_hdp((adev), (r))
 #define amdgpu_asic_need_full_reset(adev) 
(adev)->asic_funcs->need_full_reset((adev))
 #define amdgpu_asic_init_doorbell_index(adev) 
(adev)->asic_funcs->init_doorbell_index((adev))
+#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) 
((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
 
 /* Common functions */
 bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 6896dec..d2b29fd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", value);
 }
 
+/**
+ * DOC: pcie_bw
+ *
+ * The amdgpu driver provides a sysfs API for reading how much data
+ * has been sent and received by the GPU in the last second through PCIe.
+ * The file pcie_bw is used for this.
+ * The Perf counters calculate this and return the number of sent and received
+ * messages, which we multiply by the maxsize of our PCIe packets (mps).
+ * Note that it is not possible to easily and quickly obtain the size of each
+ * packet transmitted, so we use the max payload size (mps) to estimate the
+ * PCIe bandwidth usage
+ */
+static ssize_t amdgpu_get_pcie_bw(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct drm_device *ddev = dev_get_drvdata(dev);
+   struct amdgpu_device *adev = ddev->dev_private;
+   uint64_t mps = pcie_get_mps(adev->pdev);
+   uint64_t count0, count1;
+
+   amdgpu_asic_get_pcie_usage(adev, , );
+   return snprintf(buf, PAGE_SIZE,
+   "Bytes received: %llu\nBytes sent: %llu\n",
+   count0 * mps, count1 * mps);
+}
+
 static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, 
amdgpu_set_dpm_state);
 static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
   amdgpu_get_dpm_forced_performance_level,
@@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
amdgpu_set_pp_od_clk_voltage);
 static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
amdgpu_get_busy_percent, NULL);
+static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL);
 
 static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
  struct device_attribute *attr,
@@ -2108,6 +2136,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
"gpu_busy_level\n");
return ret;
}
+   /* PCIe Perf counters won't work on APU nodes */
+   if (adev->flags & !AMD_IS_APU) {
+   ret = device_create_file(adev->dev, _attr_pcie_bw);
+   if (ret) {
+   DRM_ERROR("failed to create device file pcie_bw\n");
+   return ret;
+   }
+   }
ret = amdgpu_debugfs_pm_init(adev);
if (ret) {
DRM_ERROR("Failed to register debugfs file for dpm!\n");
@@ -2147,6 +2183,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
device_remove_file(adev->dev,
_attr_pp_od_clk_voltage);
device_remove_file(adev->dev, _attr_gpu_busy_percent);
+   if (adev->flags & !AMD_IS_APU)
+   device_remove_file(adev->dev, 

[PATCH 2/2] drm/amdgpu: Add sysfs file for PCIe usage v2

2019-01-08 Thread Russell, Kent
Add a sysfs file that reports the number of bytes transmitted and
received in the last second. This can be used to approximate the PCIe
bandwidth usage over the last second.

v2: Clarify use of mps as estimation of bandwidth

Signed-off-by: Kent Russell 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 34 ++
 drivers/gpu/drm/amd/amdgpu/cik.c   | 41 +++
 drivers/gpu/drm/amd/amdgpu/si.c| 41 +++
 drivers/gpu/drm/amd/amdgpu/soc15.c | 44 ++
 drivers/gpu/drm/amd/amdgpu/vi.c| 41 +++
 6 files changed, 205 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index e1b2c64..512b124 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -542,6 +542,9 @@ struct amdgpu_asic_funcs {
bool (*need_full_reset)(struct amdgpu_device *adev);
/* initialize doorbell layout for specific asic*/
void (*init_doorbell_index)(struct amdgpu_device *adev);
+   /* PCIe bandwidth usage */
+   void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0,
+  uint64_t *count1);
 };
 
 /*
@@ -1045,6 +1048,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 #define amdgpu_asic_invalidate_hdp(adev, r) 
(adev)->asic_funcs->invalidate_hdp((adev), (r))
 #define amdgpu_asic_need_full_reset(adev) 
(adev)->asic_funcs->need_full_reset((adev))
 #define amdgpu_asic_init_doorbell_index(adev) 
(adev)->asic_funcs->init_doorbell_index((adev))
+#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) 
((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
 
 /* Common functions */
 bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 6896dec..9cf47ba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -990,6 +990,33 @@ static ssize_t amdgpu_get_busy_percent(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", value);
 }
 
+/**
+ * DOC: pcie_bw
+ *
+ * The amdgpu driver provides a sysfs API for reading how much data
+ * has been sent and received by the GPU in the last second through PCIe.
+ * The file pcie_bw is used for this.
+ * The Perf counters calculate this and return the number of sent and received
+ * messages, which we multiply by the maxsize of our PCIe packets (mps).
+ * Note that it is not possible to easily and quickly obtain the size of each
+ * packet transmitted, so we use the max payload size (mps) to estimate the
+ * PCIe bandwidth usage
+ */
+static ssize_t amdgpu_get_pcie_bw(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct drm_device *ddev = dev_get_drvdata(dev);
+   struct amdgpu_device *adev = ddev->dev_private;
+   uint64_t mps = pcie_get_mps(adev->pdev);
+   uint64_t count0, count1;
+
+   amdgpu_asic_get_pcie_usage(adev, , );
+   return snprintf(buf, PAGE_SIZE,
+   "Bytes received: %llu\nBytes sent: %llu\n",
+   count0 * mps, count1 * mps);
+}
+
 static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, 
amdgpu_set_dpm_state);
 static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
   amdgpu_get_dpm_forced_performance_level,
@@ -1025,6 +1052,7 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
amdgpu_set_pp_od_clk_voltage);
 static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
amdgpu_get_busy_percent, NULL);
+static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL);
 
 static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
  struct device_attribute *attr,
@@ -2108,6 +2136,11 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
"gpu_busy_level\n");
return ret;
}
+   ret = device_create_file(adev->dev, _attr_pcie_bw);
+   if (ret) {
+   DRM_ERROR("failed to create device file pcie_bw\n");
+   return ret;
+   }
ret = amdgpu_debugfs_pm_init(adev);
if (ret) {
DRM_ERROR("Failed to register debugfs file for dpm!\n");
@@ -2147,6 +2180,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
device_remove_file(adev->dev,
_attr_pp_od_clk_voltage);
device_remove_file(adev->dev, _attr_gpu_busy_percent);
+   device_remove_file(adev->dev, _attr_pcie_bw);
 }
 
 void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 71c50d8..8681744 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ 

  1   2   >