Re: [PATCH] drm/amd/display: Only require EDID read for HDMI and DVI

2018-08-02 Thread Nicholas Kazlauskas

On 08/02/2018 03:38 PM, Harry Wentland wrote:

[Why]
VGA sometimes has trouble retrieving the EDID on very long cables, KVM
switches, or old displays.

[How]
Only require EDID read for HDMI and DVI and exempt other types (DP,
VGA). We currently don't support VGA but if anyone adds support in the
future this might get overlooked.

Signed-off-by: Harry Wentland 
Suggested-by: Michel Dänzer 
---
  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index d6086c591f75..71b94e3b472e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -753,7 +753,8 @@ bool dc_link_detect(struct dc_link *link, enum 
dc_detect_reason reason)
 * even if we have no EDID in order to go to
 * fail-safe mode
 */
-   if (!dc_is_dp_signal(link->connector_signal))
+   if (dc_is_hdmi_signal(link->connector_signal) ||
+   dc_is_dvi_signal(link->connector_signal))
return false;
default:
break;



Looks good. Fixing the indenting or merging the conditions would be a 
good idea, however.


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


[PATCH] drm/amd/pp: Reset memory levels table before populating values

2018-08-01 Thread Nicholas Kazlauskas
[Why]

On POLARIS10 powerplay can fail to retrieve minimum memory clocks.
This cascades into failing to find the MinVddc value when
populating a single memory level. When this is called during
polaris10_populate_all_memory_levels the function exits early leaving
the previously used values in the smc_state_table.

Under these conditions visual corruption can be observed on the screen
during modesets between specific bandwidth thresholds.

[How]

There seems to be a similar problem and solution for Tonga: a memset
on the levels table before populating its values. This change fixes
the visual corruption that seems to occur when changing from a low
clock mode (640x480@75Hz) to a medium clock mode (1920x1200@60Hz).

However, this is a small fix for a symptom of the larger issue of
failing to find the MinVddc. Other hardware would seem to encounter
the same issue if the table is empty, so significant refactoring
would likely be needed.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c 
b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 1276f168ff68..68356479dac1 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -1134,6 +1134,8 @@ static int polaris10_populate_all_memory_levels(struct 
pp_hwmgr *hwmgr)
smu_data->smc_state_table.MemoryLevel;
uint32_t i;
 
+   memset(levels, 0, array_size);
+
for (i = 0; i < dpm_table->mclk_table.count; i++) {
PP_ASSERT_WITH_CODE((0 != 
dpm_table->mclk_table.dpm_levels[i].value),
"can not populate memory level as memory clock 
is zero",
-- 
2.17.1

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


Re: [PATCH v2] drm/amd/display: Report non-DP display as disconnected without EDID

2018-08-01 Thread Nicholas Kazlauskas

On 08/01/2018 03:51 PM, Harry Wentland wrote:

[Why]
Some boards seem to have a problem where HPD is high on HDMI even though
no display is connected. We don't want to report these as connected. DP
spec still requires us to report DP displays as connected when HPD is
high but we can't read the EDID in order to go to fail-safe mode.

[How]
If connector_signal is not DP abort detection if we can't retrieve the
EDID.

Bugzilla: https://bugs.freedesktop.org/107390
Bugzilla: https://bugs.freedesktop.org/106846
Cc: sta...@vger.kernel.org
Signed-off-by: Harry Wentland 
Acked-by: Alex Deucher 

v2: Add Bugzilla and stable
---
  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index b180197a41e2..84f0fd15be4c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -744,6 +744,17 @@ bool dc_link_detect(struct dc_link *link, enum 
dc_detect_reason reason)
break;
case EDID_NO_RESPONSE:
DC_LOG_ERROR("No EDID read.\n");
+
+   /*
+* Abort detection for non-DP connectors if we have
+* no EDID
+*
+* DP needs to report as connected if HDP is high
+* even if we have no EDID in order to go to
+* fail-safe mode
+*/
+   if (!dc_is_dp_signal(link->connector_signal))
+   return false;
default:
break;
}


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


[PATCH] drm/amd/display: Fix overflow/truncation from strncpy.

2018-07-20 Thread Nicholas Kazlauskas
[Why]

New GCC warnings for stringop-truncation and stringop-overflow help
catch common misuse of strncpy. This patch suppresses these warnings
by fixing bugs identified by them.

[How]

Since the parameter passed for name in amdpgu_dm_create_common_mode has
no fixed length, if the string is >= DRM_DISPLAY_MODE_LEN then
mode->name will not be null-terminated.

The truncation in fill_audio_info won't actually occur (and the string
will be null-terminated since the buffer is initialized to zero), but
the warning can be suppressed by using the proper buffer size.

This patch fixes both issues by using the real size for the buffer and
making use of strscpy (which always terminates).

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++---
 1 file changed, 3 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 8e3ebd988043..72d32dfa9f7f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2331,9 +2331,9 @@ static void fill_audio_info(struct audio_info *audio_info,
 
cea_revision = drm_connector->display_info.cea_rev;
 
-   strncpy(audio_info->display_name,
+   strscpy(audio_info->display_name,
edid_caps->display_name,
-   AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1);
+   AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS);
 
if (cea_revision >= 3) {
audio_info->mode_count = edid_caps->audio_mode_count;
@@ -3449,7 +3449,7 @@ amdgpu_dm_create_common_mode(struct drm_encoder *encoder,
mode->hdisplay = hdisplay;
mode->vdisplay = vdisplay;
mode->type &= ~DRM_MODE_TYPE_PREFERRED;
-   strncpy(mode->name, name, DRM_DISPLAY_MODE_LEN);
+   strscpy(mode->name, name, DRM_DISPLAY_MODE_LEN);
 
return mode;
 
-- 
2.17.1

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


Re: [PATCH v2] drm/amd/display: Convert 10kHz clks from PPLib into kHz for Vega

2018-07-12 Thread Nicholas Kazlauskas
This does get called from both dce120 and dce112, but it will also any 
fix any problems for dce112 as well. Looks fine to me.


Reviewed-by: Nicholas Kazlauskas 

Nicholas Kazlauskas

On 07/12/2018 10:09 AM, Harry Wentland wrote:

The driver is expecting clock frequency in kHz, while SMU returns
the values in 10kHz, which causes the bandwidth validation to fail

4.18 has the faulty clock assignment in pp_to_dc_clock_levels_with_latency
only, which is only used by Vega. Make sure we multiply these values
by 10 here, as we do for other ASICs as powerplay assigned them
wrong. 4.19 has the proper fix in powerplay.

v2: Add Fixes tag

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=107082

Signed-off-by: Mikita Lipski 
Signed-off-by: Harry Wentland 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
index 5a3346124a01..5a2e952c5bea 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
@@ -255,8 +255,9 @@ static void pp_to_dc_clock_levels_with_latency(
DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
  
  	for (i = 0; i < clk_level_info->num_levels; i++) {

-   DRM_DEBUG("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz);
-   clk_level_info->data[i].clocks_in_khz = 
pp_clks->data[i].clocks_in_khz;
+   DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", 
pp_clks->data[i].clocks_in_khz);
+   /* translate 10kHz to kHz */
+   clk_level_info->data[i].clocks_in_khz = 
pp_clks->data[i].clocks_in_khz * 10;
clk_level_info->data[i].latency_in_us = 
pp_clks->data[i].latency_in_us;
}
  }


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


[PATCH v3 0/4] A DRM API for adaptive sync and variable refresh rate support

2018-10-05 Thread Nicholas Kazlauskas
.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/189404.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/190910.html

Nicholas Kazlauskas (4):
  drm: Add vrr_capable property to the drm connector
  drm: Add vrr_enabled property to drm CRTC
  drm: Document variable refresh properties
  drm/amd/display: Set FreeSync state using drm VRR properties

 Documentation/gpu/drm-kms.rst |   7 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 drivers/gpu/drm/drm_atomic_uapi.c |   4 +
 drivers/gpu/drm/drm_connector.c   |  73 +
 drivers/gpu/drm/drm_crtc.c|   2 +
 drivers/gpu/drm/drm_mode_config.c |   6 +
 include/drm/drm_connector.h   |  15 ++
 include/drm/drm_crtc.h|   9 +
 include/drm/drm_mode_config.h |   5 +
 10 files changed, 259 insertions(+), 124 deletions(-)

-- 
2.19.0

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


[PATCH v3 1/4] drm: Add vrr_capable property to the drm connector

2018-10-05 Thread Nicholas Kazlauskas
Modern display hardware is capable of supporting variable refresh rates.
This patch introduces the "vrr_capable" property on the connector to
allow userspace to query support for variable refresh rates.

Atomic drivers should attach this property to connectors that are
capable of driving variable refresh rates using
drm_connector_attach_vrr_capable_property().

The value should be updated based on driver and hardware capabiltiy
by using drm_connector_set_vrr_capable_property().

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_connector.c | 51 +
 include/drm/drm_connector.h | 15 ++
 2 files changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1e40e5decbe9..3283703b9822 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,39 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_vrr_capable_property - creates the
+ * vrr_capable property
+ * @connector: connector to create the vrr_capable property on.
+ *
+ * This is used by atomic drivers to add support for querying
+ * variable refresh rate capability for a connector.
+ *
+ * The value from _connector_state.vrr_capable will reads
+ *
+ * Returns:
+ * Zero on success, negative errono on failure.
+ */
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->vrr_capable_property) {
+   prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
+   "vrr_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->vrr_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
@@ -1582,6 +1615,24 @@ void drm_connector_set_link_status_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_set_link_status_property);
 
+/**
+ * drm_connector_set_vrr_capable_property - sets the variable refresh rate
+ * capable property for a connector
+ * @connector: drm connector
+ * @capable: True if the connector is variable refresh rate capable
+ *
+ * Should be used by atomic drivers to update the indicated support for
+ * variable refresh rate over a connector.
+ */
+void drm_connector_set_vrr_capable_property(
+   struct drm_connector *connector, bool capable)
+{
+   return drm_object_property_set_value(>base,
+connector->vrr_capable_property,
+capable);
+}
+EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
+
 /**
  * drm_connector_init_panel_orientation_property -
  * initialize the connecters panel_orientation property
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 91a877fa00cb..b2263005234a 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -910,6 +910,17 @@ struct drm_connector {
 */
struct drm_property *scaling_mode_property;
 
+   /**
+* @vrr_capable_property: Optional property to help userspace
+* query hardware support for variable refresh rate on a connector.
+* connector. Drivers can add the property to a connector by
+* calling drm_connector_attach_vrr_capable_property().
+*
+* This should be updated only by calling
+* drm_connector_set_vrr_capable_property().
+*/
+   struct drm_property *vrr_capable_property;
+
/**
 * @content_protection_property: DRM ENUM property for content
 * protection. See drm_connector_attach_content_protection_property().
@@ -1183,6 +1194,8 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev);
 int drm_connector_attach_content_type_property(struct drm_connector *dev);
 int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
   u32 scaling_mode_mask);
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
@@ -1199,6 +1212,8 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid);
 void drm_connector_set_link_status_property(struct drm_connector *connector,
  

[PATCH v3 2/4] drm: Add vrr_enabled property to drm CRTC

2018-10-05 Thread Nicholas Kazlauskas
This patch introduces the 'vrr_enabled' CRTC property to allow
dynamic control over variable refresh rate support for a CRTC.

This property should be treated like a content hint to the driver -
if the hardware or driver is not capable of driving variable refresh
timings then this is not considered an error.

Capability for variable refresh rate support should be determined
by querying the vrr_capable drm connector property.

It is worth noting that while the property is intended for atomic use
it isn't filtered from legacy userspace queries. This allows for Xorg
userspace drivers to implement support.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic_uapi.c | 4 
 drivers/gpu/drm/drm_crtc.c| 2 ++
 drivers/gpu/drm/drm_mode_config.c | 6 ++
 include/drm/drm_crtc.h| 9 +
 include/drm/drm_mode_config.h | 5 +
 5 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d5b7f315098c..eec396a57b88 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -433,6 +433,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
drm_property_blob_put(mode);
return ret;
+   } else if (property == config->prop_vrr_enabled) {
+   state->vrr_enabled = val;
} else if (property == config->degamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
@@ -491,6 +493,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->active;
else if (property == config->prop_mode_id)
*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+   else if (property == config->prop_vrr_enabled)
+   *val = state->vrr_enabled;
else if (property == config->degamma_lut_property)
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5f488aa80bcd..e4eb2c897ff4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -340,6 +340,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
drm_object_attach_property(>base, config->prop_mode_id, 
0);
drm_object_attach_property(>base,
   config->prop_out_fence_ptr, 0);
+   drm_object_attach_property(>base,
+  config->prop_vrr_enabled, 0);
}
 
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index ee80788f2c40..5670c67f28d4 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -310,6 +310,12 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
 
+   prop = drm_property_create_bool(dev, 0,
+   "VRR_ENABLED");
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.prop_vrr_enabled = prop;
+
prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b21437bc95bf..39c3900aab3c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -290,6 +290,15 @@ struct drm_crtc_state {
 */
u32 pageflip_flags;
 
+   /**
+* @vrr_enabled:
+*
+* Indicates if variable refresh rate should be enabled for the CRTC.
+* Support for the requested vrr state will depend on driver and
+* hardware capabiltiy - lacking support is not treated as failure.
+*/
+   bool vrr_enabled;
+
/**
 * @event:
 *
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 928e4172a0bb..49f2fcfdb5fc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -639,6 +639,11 @@ struct drm_mode_config {
 * connectors must be of and active must be set to disabled, too.
 */
struct drm_property *prop_mode_id;
+   /**
+* @prop_vrr_enabled: Default atomic CRTC property to indicate
+* whether variable refresh rate should be enabled on the CRTC.
+*/
+   struct drm_property *prop_vrr_enabled;
 
/**
 * @dvi_i_subconnector_property: Optional DVI-I property to
-- 
2.19.0

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


[PATCH v3 3/4] drm: Document variable refresh properties

2018-10-05 Thread Nicholas Kazlauskas
These include the drm_connector 'vrr_capable' and the drm_crtc
'vrr_enabled' properties.

Signed-off-by: Nicholas Kazlauskas 
---
 Documentation/gpu/drm-kms.rst   |  7 +++
 drivers/gpu/drm/drm_connector.c | 22 ++
 2 files changed, 29 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 4b1501b4835b..8da2a178cf85 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -575,6 +575,13 @@ Explicit Fencing Properties
 .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
:doc: explicit fencing properties
 
+
+Variable Refresh Properties
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+   :doc: Variable refresh properties
+
 Existing KMS Properties
 ---
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 3283703b9822..3b786f3c47ef 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,28 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * DOC: Variable refresh properties
+ *
+ * Variable refresh rate control is supported via properties on the
+ * _connector and _crtc objects.
+ *
+ * "vrr_capable":
+ * Optional _connector boolean property that drivers should attach
+ * with drm_connector_attach_vrr_capable_property() on connectors that
+ * could support variable refresh rates. Drivers should update the
+ * property value by calling drm_connector_set_vrr_capable_property().
+ *
+ * Absence of the property should indicate absence of support.
+ *
+ * "vrr_enabled":
+ * Default _crtc boolean property that notifies the driver that the
+ * variable refresh rate adjustment should be enabled for the CRTC.
+ *
+ * Support for variable refresh rate will depend on the "vrr_capable"
+ * property exposed on the _connector object.
+ */
+
 /**
  * drm_connector_attach_vrr_capable_property - creates the
  * vrr_capable property
-- 
2.19.0

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


[PATCH v3 4/4] drm/amd/display: Set FreeSync state using drm VRR properties

2018-10-05 Thread Nicholas Kazlauskas
Support for AMDGPU specific FreeSync properties and ioctls are dropped
from amdgpu_dm in favor of supporting drm variable refresh rate
properties.

The drm vrr_capable property is now attached to any DP/HDMI connector.
Its value is updated accordingly to the connector's FreeSync capabiltiy.

The freesync_enable logic and ioctl control has has been dropped in
favor of utilizing the vrr_enabled on the drm CRTC. This allows for more
fine grained atomic control over which CRTCs should support variable
refresh rate.

To handle state changes for vrr_enabled it was easiest to drop the
forced modeset on freesync_enabled change. This patch now performs the
required strema updates when planes are flipped.

This is done for a few reasons:

(1) VRR stream updates can be done in the fast update path

(2) amdgpu_dm_atomic_check would have had to been hacked apart to check
desired variable refresh state and capability before the CRTC
disable pass.

(3) Performing VRR stream updates on-flip is needed for enabling BTR
support.

VRR packets and timing adjustments are now tracked and compared to
previous values sent to the hardware.

Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 2 files changed, 138 insertions(+), 124 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 6a2342d72742..0a608e31ad95 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1802,72 +1802,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->freesync_enabled = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static const struct amdgpu_display_funcs dm_display_funcs = {
.bandwidth_update = dm_bandwidth_update, /* called unconditionally */
@@ -1881,7 +1815,6 @@ static const struct amdgpu_display_funcs dm_display_funcs 
= {
dm_crtc_get_scanoutpos,/* called unconditionally */
.add_encoder = NULL, /* VBIOS parsing. DAL does it. */
.add_connector = NULL, /* VBIOS parsing. DAL does it. */
-   .notify_freesync = amdgpu_notify_freesync,
 
 };
 
@@ -2834,7 +2767,8 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
 
state->adjust = cur->adjust;
state->vrr_infopacket = cur->vrr_infopacket;
-   state->freesync_enabled = cur->freesync_enabled;
+   state->vrr_supported = cur->vrr_supported;
+   state->freesync_config = cur->freesync_config;
 
/* TODO Duplicate dc_stream after objects are stream object is 
flattened */
 
@@ -3053,8 +2987,6 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
__drm_atomic_helper_connector_duplicate_state(connector, 
_state->

[PATCH v4 0/4] A DRM API for adaptive sync and variable refresh rate support

2018-10-11 Thread Nicholas Kazlauskas
scussions ===

These patches are based upon feedback from previous threads on the subject. 
These are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/189404.htm
https://lists.freedesktop.org/archives/dri-devel/2018-September/190910.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192211.html

Nicholas Kazlauskas (4):
  drm: Add vrr_capable property to the drm connector
  drm: Add vrr_enabled property to drm CRTC
  drm: Document variable refresh properties
  drm/amd/display: Set FreeSync state using drm VRR properties

 Documentation/gpu/drm-kms.rst |   7 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 drivers/gpu/drm/drm_atomic_uapi.c |   4 +
 drivers/gpu/drm/drm_connector.c   |  71 +
 drivers/gpu/drm/drm_crtc.c|   2 +
 drivers/gpu/drm/drm_mode_config.c |   6 +
 include/drm/drm_connector.h   |  15 ++
 include/drm/drm_crtc.h|   9 +
 include/drm/drm_mode_config.h |   5 +
 10 files changed, 257 insertions(+), 124 deletions(-)

-- 
2.19.1

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


[PATCH v4 3/4] drm: Document variable refresh properties

2018-10-11 Thread Nicholas Kazlauskas
These include the drm_connector 'vrr_capable' and the drm_crtc
'vrr_enabled' properties.

Signed-off-by: Nicholas Kazlauskas 
---
 Documentation/gpu/drm-kms.rst   |  7 +++
 drivers/gpu/drm/drm_connector.c | 22 ++
 2 files changed, 29 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 4b1501b4835b..8da2a178cf85 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -575,6 +575,13 @@ Explicit Fencing Properties
 .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
:doc: explicit fencing properties
 
+
+Variable Refresh Properties
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+   :doc: Variable refresh properties
+
 Existing KMS Properties
 ---
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index f0deeb7298d0..2a12853ca917 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,28 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * DOC: Variable refresh properties
+ *
+ * Variable refresh rate control is supported via properties on the
+ * _connector and _crtc objects.
+ *
+ * "vrr_capable":
+ * Optional _connector boolean property that drivers should attach
+ * with drm_connector_attach_vrr_capable_property() on connectors that
+ * could support variable refresh rates. Drivers should update the
+ * property value by calling drm_connector_set_vrr_capable_property().
+ *
+ * Absence of the property should indicate absence of support.
+ *
+ * "vrr_enabled":
+ * Default _crtc boolean property that notifies the driver that the
+ * variable refresh rate adjustment should be enabled for the CRTC.
+ *
+ * Support for variable refresh rate will depend on the "vrr_capable"
+ * property exposed on the _connector object.
+ */
+
 /**
  * drm_connector_attach_vrr_capable_property - creates the
  * vrr_capable property
-- 
2.19.1

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


[PATCH v4 2/4] drm: Add vrr_enabled property to drm CRTC

2018-10-11 Thread Nicholas Kazlauskas
This patch introduces the 'vrr_enabled' CRTC property to allow
dynamic control over variable refresh rate support for a CRTC.

This property should be treated like a content hint to the driver -
if the hardware or driver is not capable of driving variable refresh
timings then this is not considered an error.

Capability for variable refresh rate support should be determined
by querying the vrr_capable drm connector property.

It is worth noting that while the property is intended for atomic use
it isn't filtered from legacy userspace queries. This allows for Xorg
userspace drivers to implement support.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic_uapi.c | 4 
 drivers/gpu/drm/drm_crtc.c| 2 ++
 drivers/gpu/drm/drm_mode_config.c | 6 ++
 include/drm/drm_crtc.h| 9 +
 include/drm/drm_mode_config.h | 5 +
 5 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d5b7f315098c..eec396a57b88 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -433,6 +433,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
drm_property_blob_put(mode);
return ret;
+   } else if (property == config->prop_vrr_enabled) {
+   state->vrr_enabled = val;
} else if (property == config->degamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
@@ -491,6 +493,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->active;
else if (property == config->prop_mode_id)
*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+   else if (property == config->prop_vrr_enabled)
+   *val = state->vrr_enabled;
else if (property == config->degamma_lut_property)
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5f488aa80bcd..e4eb2c897ff4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -340,6 +340,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
drm_object_attach_property(>base, config->prop_mode_id, 
0);
drm_object_attach_property(>base,
   config->prop_out_fence_ptr, 0);
+   drm_object_attach_property(>base,
+  config->prop_vrr_enabled, 0);
}
 
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index ee80788f2c40..5670c67f28d4 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -310,6 +310,12 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
 
+   prop = drm_property_create_bool(dev, 0,
+   "VRR_ENABLED");
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.prop_vrr_enabled = prop;
+
prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b21437bc95bf..39c3900aab3c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -290,6 +290,15 @@ struct drm_crtc_state {
 */
u32 pageflip_flags;
 
+   /**
+* @vrr_enabled:
+*
+* Indicates if variable refresh rate should be enabled for the CRTC.
+* Support for the requested vrr state will depend on driver and
+* hardware capabiltiy - lacking support is not treated as failure.
+*/
+   bool vrr_enabled;
+
/**
 * @event:
 *
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 928e4172a0bb..49f2fcfdb5fc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -639,6 +639,11 @@ struct drm_mode_config {
 * connectors must be of and active must be set to disabled, too.
 */
struct drm_property *prop_mode_id;
+   /**
+* @prop_vrr_enabled: Default atomic CRTC property to indicate
+* whether variable refresh rate should be enabled on the CRTC.
+*/
+   struct drm_property *prop_vrr_enabled;
 
/**
 * @dvi_i_subconnector_property: Optional DVI-I property to
-- 
2.19.1

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


[PATCH v4 1/4] drm: Add vrr_capable property to the drm connector

2018-10-11 Thread Nicholas Kazlauskas
Modern display hardware is capable of supporting variable refresh rates.
This patch introduces the "vrr_capable" property on the connector to
allow userspace to query support for variable refresh rates.

Atomic drivers should attach this property to connectors that are
capable of driving variable refresh rates using
drm_connector_attach_vrr_capable_property().

The value should be updated based on driver and hardware capabiltiy
by using drm_connector_set_vrr_capable_property().

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_connector.c | 49 +
 include/drm/drm_connector.h | 15 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1e40e5decbe9..f0deeb7298d0 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,37 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_vrr_capable_property - creates the
+ * vrr_capable property
+ * @connector: connector to create the vrr_capable property on.
+ *
+ * This is used by atomic drivers to add support for querying
+ * variable refresh rate capability for a connector.
+ *
+ * Returns:
+ * Zero on success, negative errono on failure.
+ */
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->vrr_capable_property) {
+   prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
+   "vrr_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->vrr_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
@@ -1582,6 +1613,24 @@ void drm_connector_set_link_status_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_set_link_status_property);
 
+/**
+ * drm_connector_set_vrr_capable_property - sets the variable refresh rate
+ * capable property for a connector
+ * @connector: drm connector
+ * @capable: True if the connector is variable refresh rate capable
+ *
+ * Should be used by atomic drivers to update the indicated support for
+ * variable refresh rate over a connector.
+ */
+void drm_connector_set_vrr_capable_property(
+   struct drm_connector *connector, bool capable)
+{
+   drm_object_property_set_value(>base,
+ connector->vrr_capable_property,
+ capable);
+}
+EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
+
 /**
  * drm_connector_init_panel_orientation_property -
  * initialize the connecters panel_orientation property
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 91a877fa00cb..b2263005234a 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -910,6 +910,17 @@ struct drm_connector {
 */
struct drm_property *scaling_mode_property;
 
+   /**
+* @vrr_capable_property: Optional property to help userspace
+* query hardware support for variable refresh rate on a connector.
+* connector. Drivers can add the property to a connector by
+* calling drm_connector_attach_vrr_capable_property().
+*
+* This should be updated only by calling
+* drm_connector_set_vrr_capable_property().
+*/
+   struct drm_property *vrr_capable_property;
+
/**
 * @content_protection_property: DRM ENUM property for content
 * protection. See drm_connector_attach_content_protection_property().
@@ -1183,6 +1194,8 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev);
 int drm_connector_attach_content_type_property(struct drm_connector *dev);
 int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
   u32 scaling_mode_mask);
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
@@ -1199,6 +1212,8 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid);
 void drm_connector_set_link_status_property(struct drm_connector *connector,
uint64_t link_status);
+void drm_connector_set_vrr_ca

[PATCH v4 4/4] drm/amd/display: Set FreeSync state using drm VRR properties

2018-10-11 Thread Nicholas Kazlauskas
Support for AMDGPU specific FreeSync properties and ioctls are dropped
from amdgpu_dm in favor of supporting drm variable refresh rate
properties.

The drm vrr_capable property is now attached to any DP/HDMI connector.
Its value is updated accordingly to the connector's FreeSync capabiltiy.

The freesync_enable logic and ioctl control has has been dropped in
favor of utilizing the vrr_enabled on the drm CRTC. This allows for more
fine grained atomic control over which CRTCs should support variable
refresh rate.

To handle state changes for vrr_enabled it was easiest to drop the
forced modeset on freesync_enabled change. This patch now performs the
required stream updates when planes are flipped.

This is done for a few reasons:

(1) VRR stream updates can be done in the fast update path

(2) amdgpu_dm_atomic_check would need to be hacked apart to check
desired variable refresh state and capability before the CRTC
disable pass.

(3) Performing VRR stream updates on-flip is needed for enabling BTR
support.

VRR packets and timing adjustments are now tracked and compared to
previous values sent to the hardware.

Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 2 files changed, 138 insertions(+), 124 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 6a2342d72742..d5de4b91e144 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1802,72 +1802,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->freesync_enabled = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static const struct amdgpu_display_funcs dm_display_funcs = {
.bandwidth_update = dm_bandwidth_update, /* called unconditionally */
@@ -1881,7 +1815,6 @@ static const struct amdgpu_display_funcs dm_display_funcs 
= {
dm_crtc_get_scanoutpos,/* called unconditionally */
.add_encoder = NULL, /* VBIOS parsing. DAL does it. */
.add_connector = NULL, /* VBIOS parsing. DAL does it. */
-   .notify_freesync = amdgpu_notify_freesync,
 
 };
 
@@ -2834,7 +2767,8 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
 
state->adjust = cur->adjust;
state->vrr_infopacket = cur->vrr_infopacket;
-   state->freesync_enabled = cur->freesync_enabled;
+   state->vrr_supported = cur->vrr_supported;
+   state->freesync_config = cur->freesync_config;
 
/* TODO Duplicate dc_stream after objects are stream object is 
flattened */
 
@@ -3053,8 +2987,6 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
__drm_atomic_helper_connector_duplicate_state(connector, 
_state->base);

[PATCH v5 0/4] A DRM API for adaptive sync and variable refresh rate support

2018-10-12 Thread Nicholas Kazlauskas
 in their 
respective mailing lists and the xf86-video-amdgpu GitLab.

=== Previous discussions ===

These patches are based upon feedback from previous threads on the subject. 
These are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/189404.htm
https://lists.freedesktop.org/archives/dri-devel/2018-September/190910.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192211.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192874.html

Nicholas Kazlauskas (4):
  drm: Add vrr_capable property to the drm connector
  drm: Add vrr_enabled property to drm CRTC
  drm: Document variable refresh properties
  drm/amdgpu: Set FreeSync state using drm VRR properties

 Documentation/gpu/drm-kms.rst |   7 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   7 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 drivers/gpu/drm/drm_atomic_uapi.c |   4 +
 drivers/gpu/drm/drm_connector.c   |  71 +
 drivers/gpu/drm/drm_crtc.c|   2 +
 drivers/gpu/drm/drm_mode_config.c |   6 +
 include/drm/drm_connector.h   |  15 ++
 include/drm/drm_crtc.h|   9 +
 include/drm/drm_mode_config.h |   5 +
 11 files changed, 257 insertions(+), 131 deletions(-)

-- 
2.19.1

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


[PATCH v5 1/4] drm: Add vrr_capable property to the drm connector

2018-10-12 Thread Nicholas Kazlauskas
Modern display hardware is capable of supporting variable refresh rates.
This patch introduces the "vrr_capable" property on the connector to
allow userspace to query support for variable refresh rates.

Atomic drivers should attach this property to connectors that are
capable of driving variable refresh rates using
drm_connector_attach_vrr_capable_property().

The value should be updated based on driver and hardware capabiltiy
by using drm_connector_set_vrr_capable_property().

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_connector.c | 49 +
 include/drm/drm_connector.h | 15 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1e40e5decbe9..f0deeb7298d0 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,37 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_vrr_capable_property - creates the
+ * vrr_capable property
+ * @connector: connector to create the vrr_capable property on.
+ *
+ * This is used by atomic drivers to add support for querying
+ * variable refresh rate capability for a connector.
+ *
+ * Returns:
+ * Zero on success, negative errono on failure.
+ */
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->vrr_capable_property) {
+   prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
+   "vrr_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->vrr_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
@@ -1582,6 +1613,24 @@ void drm_connector_set_link_status_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_set_link_status_property);
 
+/**
+ * drm_connector_set_vrr_capable_property - sets the variable refresh rate
+ * capable property for a connector
+ * @connector: drm connector
+ * @capable: True if the connector is variable refresh rate capable
+ *
+ * Should be used by atomic drivers to update the indicated support for
+ * variable refresh rate over a connector.
+ */
+void drm_connector_set_vrr_capable_property(
+   struct drm_connector *connector, bool capable)
+{
+   drm_object_property_set_value(>base,
+ connector->vrr_capable_property,
+ capable);
+}
+EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
+
 /**
  * drm_connector_init_panel_orientation_property -
  * initialize the connecters panel_orientation property
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 91a877fa00cb..b2263005234a 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -910,6 +910,17 @@ struct drm_connector {
 */
struct drm_property *scaling_mode_property;
 
+   /**
+* @vrr_capable_property: Optional property to help userspace
+* query hardware support for variable refresh rate on a connector.
+* connector. Drivers can add the property to a connector by
+* calling drm_connector_attach_vrr_capable_property().
+*
+* This should be updated only by calling
+* drm_connector_set_vrr_capable_property().
+*/
+   struct drm_property *vrr_capable_property;
+
/**
 * @content_protection_property: DRM ENUM property for content
 * protection. See drm_connector_attach_content_protection_property().
@@ -1183,6 +1194,8 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev);
 int drm_connector_attach_content_type_property(struct drm_connector *dev);
 int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
   u32 scaling_mode_mask);
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
@@ -1199,6 +1212,8 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid);
 void drm_connector_set_link_status_property(struct drm_connector *connector,
uint64_t link_status);
+void drm_connector_set_vrr_ca

[PATCH v5 4/4] drm/amdgpu: Set FreeSync state using drm VRR properties

2018-10-12 Thread Nicholas Kazlauskas
Support for AMDGPU specific FreeSync properties and ioctls are dropped
from amdgpu_dm in favor of supporting drm variable refresh rate
properties.

The notify_freesync and set_freesync_property functions are dropped
from amdgpu_display_funcs.

The drm vrr_capable property is now attached to any DP/HDMI connector.
Its value is updated accordingly to the connector's FreeSync capabiltiy.

The freesync_enable logic and ioctl control has has been dropped in
favor of utilizing the vrr_enabled on the drm CRTC. This allows for more
fine grained atomic control over which CRTCs should support variable
refresh rate.

To handle state changes for vrr_enabled it was easiest to drop the
forced modeset on freesync_enabled change. This patch now performs the
required stream updates when planes are flipped.

This is done for a few reasons:

(1) VRR stream updates can be done in the fast update path

(2) amdgpu_dm_atomic_check would need to be hacked apart to check
desired variable refresh state and capability before the CRTC
disable pass.

(3) Performing VRR stream updates on-flip is needed for enabling BTR
support.

VRR packets and timing adjustments are now tracked and compared to
previous values sent to the hardware.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   7 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 3 files changed, 138 insertions(+), 131 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b9e9e8b02fb7..0cbe867ec375 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -295,13 +295,6 @@ struct amdgpu_display_funcs {
  uint16_t connector_object_id,
  struct amdgpu_hpd *hpd,
  struct amdgpu_router *router);
-   /* it is used to enter or exit into free sync mode */
-   int (*notify_freesync)(struct drm_device *dev, void *data,
-  struct drm_file *filp);
-   /* it is used to allow enablement of freesync mode */
-   int (*set_freesync_property)(struct drm_connector *connector,
-struct drm_property *property,
-uint64_t val);
 
 
 };
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 e224f23e2215..f6af388cc32d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1802,72 +1802,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->freesync_enabled = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static const struct amdgpu_display_funcs dm_d

[PATCH v5 2/4] drm: Add vrr_enabled property to drm CRTC

2018-10-12 Thread Nicholas Kazlauskas
This patch introduces the 'vrr_enabled' CRTC property to allow
dynamic control over variable refresh rate support for a CRTC.

This property should be treated like a content hint to the driver -
if the hardware or driver is not capable of driving variable refresh
timings then this is not considered an error.

Capability for variable refresh rate support should be determined
by querying the vrr_capable drm connector property.

It is worth noting that while the property is intended for atomic use
it isn't filtered from legacy userspace queries. This allows for Xorg
userspace drivers to implement support.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic_uapi.c | 4 
 drivers/gpu/drm/drm_crtc.c| 2 ++
 drivers/gpu/drm/drm_mode_config.c | 6 ++
 include/drm/drm_crtc.h| 9 +
 include/drm/drm_mode_config.h | 5 +
 5 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d5b7f315098c..eec396a57b88 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -433,6 +433,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
drm_property_blob_put(mode);
return ret;
+   } else if (property == config->prop_vrr_enabled) {
+   state->vrr_enabled = val;
} else if (property == config->degamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
@@ -491,6 +493,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->active;
else if (property == config->prop_mode_id)
*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+   else if (property == config->prop_vrr_enabled)
+   *val = state->vrr_enabled;
else if (property == config->degamma_lut_property)
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5f488aa80bcd..e4eb2c897ff4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -340,6 +340,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
drm_object_attach_property(>base, config->prop_mode_id, 
0);
drm_object_attach_property(>base,
   config->prop_out_fence_ptr, 0);
+   drm_object_attach_property(>base,
+  config->prop_vrr_enabled, 0);
}
 
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index ee80788f2c40..5670c67f28d4 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -310,6 +310,12 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
 
+   prop = drm_property_create_bool(dev, 0,
+   "VRR_ENABLED");
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.prop_vrr_enabled = prop;
+
prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b21437bc95bf..39c3900aab3c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -290,6 +290,15 @@ struct drm_crtc_state {
 */
u32 pageflip_flags;
 
+   /**
+* @vrr_enabled:
+*
+* Indicates if variable refresh rate should be enabled for the CRTC.
+* Support for the requested vrr state will depend on driver and
+* hardware capabiltiy - lacking support is not treated as failure.
+*/
+   bool vrr_enabled;
+
/**
 * @event:
 *
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 928e4172a0bb..49f2fcfdb5fc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -639,6 +639,11 @@ struct drm_mode_config {
 * connectors must be of and active must be set to disabled, too.
 */
struct drm_property *prop_mode_id;
+   /**
+* @prop_vrr_enabled: Default atomic CRTC property to indicate
+* whether variable refresh rate should be enabled on the CRTC.
+*/
+   struct drm_property *prop_vrr_enabled;
 
/**
 * @dvi_i_subconnector_property: Optional DVI-I property to
-- 
2.19.1

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


[PATCH v5 3/4] drm: Document variable refresh properties

2018-10-12 Thread Nicholas Kazlauskas
These include the drm_connector 'vrr_capable' and the drm_crtc
'vrr_enabled' properties.

Signed-off-by: Nicholas Kazlauskas 
---
 Documentation/gpu/drm-kms.rst   |  7 +++
 drivers/gpu/drm/drm_connector.c | 22 ++
 2 files changed, 29 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 4b1501b4835b..8da2a178cf85 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -575,6 +575,13 @@ Explicit Fencing Properties
 .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
:doc: explicit fencing properties
 
+
+Variable Refresh Properties
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+   :doc: Variable refresh properties
+
 Existing KMS Properties
 ---
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index f0deeb7298d0..2a12853ca917 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,28 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * DOC: Variable refresh properties
+ *
+ * Variable refresh rate control is supported via properties on the
+ * _connector and _crtc objects.
+ *
+ * "vrr_capable":
+ * Optional _connector boolean property that drivers should attach
+ * with drm_connector_attach_vrr_capable_property() on connectors that
+ * could support variable refresh rates. Drivers should update the
+ * property value by calling drm_connector_set_vrr_capable_property().
+ *
+ * Absence of the property should indicate absence of support.
+ *
+ * "vrr_enabled":
+ * Default _crtc boolean property that notifies the driver that the
+ * variable refresh rate adjustment should be enabled for the CRTC.
+ *
+ * Support for variable refresh rate will depend on the "vrr_capable"
+ * property exposed on the _connector object.
+ */
+
 /**
  * drm_connector_attach_vrr_capable_property - creates the
  * vrr_capable property
-- 
2.19.1

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


[PATCH] drm/amdgpu: Add DCC flags for GFX9 amdgpu_bo

2018-10-23 Thread Nicholas Kazlauskas
[Why]
Hardware support for Delta Color Compression (DCC) decompression is
available in DC for GFX9 but there's no way for userspace to enable
the feature.

Enabling the feature can provide improved GFX performance and
power savings in many situations.

[How]
Extend the GFX9 tiling flags to include DCC parameters. These are
logically grouped together with tiling flags even if they are
technically distinct.

This trivially maintains backwards compatibility with existing
users of amdgpu_gem_metadata. No new IOCTls or data structures are
needed to support DCC.

This patch helps expose DCC attributes to both libdrm and amdgpu_dm.

Signed-off-by: Nicholas Kazlauskas 
---
 include/uapi/drm/amdgpu_drm.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 6a0d77dcfc47..faaad04814e4 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -329,6 +329,12 @@ struct drm_amdgpu_gem_userptr {
 /* GFX9 and later: */
 #define AMDGPU_TILING_SWIZZLE_MODE_SHIFT   0
 #define AMDGPU_TILING_SWIZZLE_MODE_MASK0x1f
+#define AMDGPU_TILING_DCC_OFFSET_256B_SHIFT5
+#define AMDGPU_TILING_DCC_OFFSET_256B_MASK 0xFF
+#define AMDGPU_TILING_DCC_PITCH_MAX_SHIFT  29
+#define AMDGPU_TILING_DCC_PITCH_MAX_MASK   0x3FFF
+#define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT43
+#define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1
 
 /* Set/Get helpers for tiling flags. */
 #define AMDGPU_TILING_SET(field, value) \
-- 
2.17.1

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


[PATCH v2 2/2] drm/amd/display: Support amdgpu "max bpc" connector property

2018-11-07 Thread Nicholas Kazlauskas
[Why]
Many panels support more than 8bpc but some modes are unavailable while
running at greater than 8bpc due to DP/HDMI bandwidth constraints.

Support for more than 8bpc was added recently in the driver but it
defaults to the maximum supported bpc - locking out these modes.

This should be a user configurable option such that the user can select
what bpc configuration they would like.

[How]
This patch adds support for getting and setting the amdgpu driver
specific "max bpc" property on the connector.

It also adds support for limiting the output bpc based on the property
value. The default limitation is the lowest value in the range, 8bpc.
This was the old value before the range was uncapped.

This patch should be updated/replaced later once common drm support
for max bpc lands.

Bugzilla: https://bugs.freedesktop.org/108542
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=201585
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200645
Fixes: e03fd3f300f6 ("drm/amd/display: Do not limit color depth to 8bpc")

Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c| 16 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h|  1 +
 2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c440d967db57..6b746afc55e7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2417,8 +2417,15 @@ static void update_stream_scaling_settings(const struct 
drm_display_mode *mode,
 static enum dc_color_depth
 convert_color_depth_from_display_info(const struct drm_connector *connector)
 {
+   struct dm_connector_state *dm_conn_state =
+   to_dm_connector_state(connector->state);
uint32_t bpc = connector->display_info.bpc;
 
+   /* TODO: Remove this when there's support for max_bpc in drm */
+   if (dm_conn_state && bpc > dm_conn_state->max_bpc)
+   /* Round down to nearest even number. */
+   bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1);
+
switch (bpc) {
case 0:
/*
@@ -3001,6 +3008,9 @@ int amdgpu_dm_connector_atomic_set_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
dm_new_state->underscan_enable = val;
ret = 0;
+   } else if (property == adev->mode_info.max_bpc_property) {
+   dm_new_state->max_bpc = val;
+   ret = 0;
} else if (property == adev->mode_info.freesync_property) {
dm_new_state->freesync_enable = val;
ret = 0;
@@ -3049,6 +3059,9 @@ int amdgpu_dm_connector_atomic_get_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
*val = dm_state->underscan_enable;
ret = 0;
+   } else if (property == adev->mode_info.max_bpc_property) {
+   *val = dm_state->max_bpc;
+   ret = 0;
} else if (property == adev->mode_info.freesync_property) {
*val = dm_state->freesync_enable;
ret = 0;
@@ -3864,6 +3877,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(>base.base,
adev->mode_info.underscan_vborder_property,
0);
+   drm_object_attach_property(>base.base,
+   adev->mode_info.max_bpc_property,
+   0);
 
if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 23f2d05cf07e..afcb9842bb45 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -252,6 +252,7 @@ struct dm_connector_state {
enum amdgpu_rmx_type scaling;
uint8_t underscan_vborder;
uint8_t underscan_hborder;
+   uint8_t max_bpc;
bool underscan_enable;
bool freesync_enable;
bool freesync_capable;
-- 
2.17.1

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


[PATCH v2 1/2] drm/amdgpu: Add amdgpu "max bpc" connector property

2018-11-07 Thread Nicholas Kazlauskas
[Why]
Many panels support more than 8bpc but some modes are unavailable while
running at greater than 8bpc due to DP/HDMI bandwidth constraints.

Support for more than 8bpc was added recently in the driver but it
defaults to the maximum supported bpc - locking out these modes.

This should be a user configurable option such that the user can select
what bpc configuration they would like.

[How]
This patch introduces the "max bpc" amdgpu driver specific connector
property so the user can limit the maximum bpc. It ranges from 8 to 16.

This doesn't directly set the preferred bpc for the panel since it
follows Intel's existing driver conventions.

This proprety should be removed once common drm support for max bpc
lands.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 5 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h| 2 ++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 7d6a36bca9dd..292bfd5340fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -626,6 +626,11 @@ int amdgpu_display_modeset_create_props(struct 
amdgpu_device *adev)
 "dither",
 amdgpu_dither_enum_list, sz);
 
+   adev->mode_info.max_bpc_property =
+   drm_property_create_range(adev->ddev, 0, "max bpc", 8, 16);
+   if (!adev->mode_info.max_bpc_property)
+   return -ENOMEM;
+
if (amdgpu_device_has_dc_support(adev)) {
adev->mode_info.freesync_property =
drm_property_create_bool(adev->ddev, 0, "freesync");
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1627dd3413c7..c39af5d79608 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -338,6 +338,8 @@ struct amdgpu_mode_info {
struct drm_property *audio_property;
/* FMT dithering */
struct drm_property *dither_property;
+   /* maximum number of bits per channel for monitor color */
+   struct drm_property *max_bpc_property;
/* it is used to allow enablement of freesync mode */
struct drm_property *freesync_property;
/* it is used to know about display capability of freesync mode */
-- 
2.17.1

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


[PATCH v7 0/5] A DRM API for adaptive sync and variable refresh rate support

2018-11-08 Thread Nicholas Kazlauskas
 monitor setup. They also work on KDE in a 
single monitor setup with the compositor disabled.

The patches require that suitable applications flip via the Present extension 
to xf86-video-amdgpu for the entire Screen. Some compositors may interfere with 
this if they are unable to unredirect the window.

Full implementation details for these changes can be reviewed in their 
respective mailing lists and the xf86-video-amdgpu GitLab.

=== Previous discussions ===

These patches are based upon feedback from previous threads on the subject. 
These are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/189404.htm
https://lists.freedesktop.org/archives/dri-devel/2018-September/190910.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192211.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192874.html

Nicholas Kazlauskas (5):
  drm: Add vrr_capable property to the drm connector
  drm: Add vrr_enabled property to drm CRTC
  drm: Document variable refresh properties
  drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal
  drm/amdgpu: Set FreeSync state using drm VRR properties

 Documentation/gpu/drm-kms.rst |   7 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |   7 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   7 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 drivers/gpu/drm/drm_atomic_uapi.c |   4 +
 drivers/gpu/drm/drm_connector.c   | 117 
 drivers/gpu/drm/drm_crtc.c|   2 +
 drivers/gpu/drm/drm_mode_config.c |   6 +
 include/drm/drm_connector.h   |  15 ++
 include/drm/drm_crtc.h|   9 +
 include/drm/drm_mode_config.h |   5 +
 12 files changed, 309 insertions(+), 132 deletions(-)

-- 
2.19.1

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


[PATCH v7 4/5] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2018-11-08 Thread Nicholas Kazlauskas
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 
Cc: Michel Dänzer 
---
 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 6748cd7fc129..cb331319f225 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -850,7 +850,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 v7 1/5] drm: Add vrr_capable property to the drm connector

2018-11-08 Thread Nicholas Kazlauskas
Modern display hardware is capable of supporting variable refresh rates.
This patch introduces the "vrr_capable" property on the connector to
allow userspace to query support for variable refresh rates.

Atomic drivers should attach this property to connectors that are
capable of driving variable refresh rates using
drm_connector_attach_vrr_capable_property().

The value should be updated based on driver and hardware capability
by using drm_connector_set_vrr_capable_property().

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Manasi Navare 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/drm_connector.c | 49 +
 include/drm/drm_connector.h | 15 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 4943cef178be..49290060ab7b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1255,6 +1255,37 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_vrr_capable_property - creates the
+ * vrr_capable property
+ * @connector: connector to create the vrr_capable property on.
+ *
+ * This is used by atomic drivers to add support for querying
+ * variable refresh rate capability for a connector.
+ *
+ * Returns:
+ * Zero on success, negative errono on failure.
+ */
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->vrr_capable_property) {
+   prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
+   "vrr_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->vrr_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
@@ -1583,6 +1614,24 @@ void drm_connector_set_link_status_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_set_link_status_property);
 
+/**
+ * drm_connector_set_vrr_capable_property - sets the variable refresh rate
+ * capable property for a connector
+ * @connector: drm connector
+ * @capable: True if the connector is variable refresh rate capable
+ *
+ * Should be used by atomic drivers to update the indicated support for
+ * variable refresh rate over a connector.
+ */
+void drm_connector_set_vrr_capable_property(
+   struct drm_connector *connector, bool capable)
+{
+   drm_object_property_set_value(>base,
+ connector->vrr_capable_property,
+ capable);
+}
+EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
+
 /**
  * drm_connector_init_panel_orientation_property -
  * initialize the connecters panel_orientation property
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 9ccad6b062f2..4e6befff153b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -959,6 +959,17 @@ struct drm_connector {
 */
struct drm_property *scaling_mode_property;
 
+   /**
+* @vrr_capable_property: Optional property to help userspace
+* query hardware support for variable refresh rate on a connector.
+* connector. Drivers can add the property to a connector by
+* calling drm_connector_attach_vrr_capable_property().
+*
+* This should be updated only by calling
+* drm_connector_set_vrr_capable_property().
+*/
+   struct drm_property *vrr_capable_property;
+
/**
 * @content_protection_property: DRM ENUM property for content
 * protection. See drm_connector_attach_content_protection_property().
@@ -1250,6 +1261,8 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev);
 int drm_connector_attach_content_type_property(struct drm_connector *dev);
 int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
   u32 scaling_mode_mask);
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
@@ -1266,6 +1279,8 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid);
 void drm_connector_set_link_status_property(struct drm_connector *connector,
  

[PATCH v7 5/5] drm/amdgpu: Set FreeSync state using drm VRR properties

2018-11-08 Thread Nicholas Kazlauskas
Support for AMDGPU specific FreeSync properties and ioctls are dropped
from amdgpu_dm in favor of supporting drm variable refresh rate
properties.

The notify_freesync and set_freesync_property functions are dropped
from amdgpu_display_funcs.

The drm vrr_capable property is now attached to any DP/HDMI connector.
Its value is updated accordingly to the connector's FreeSync capabiltiy.

The freesync_enable logic and ioctl control has has been dropped in
favor of utilizing the vrr_enabled on the drm CRTC. This allows for more
fine grained atomic control over which CRTCs should support variable
refresh rate.

To handle state changes for vrr_enabled it was easiest to drop the
forced modeset on freesync_enabled change. This patch now performs the
required stream updates when planes are flipped.

This is done for a few reasons:

(1) VRR stream updates can be done in the fast update path

(2) amdgpu_dm_atomic_check would need to be hacked apart to check
desired variable refresh state and capability before the CRTC
disable pass.

(3) Performing VRR stream updates on-flip is needed for enabling BTR
support.

VRR packets and timing adjustments are now tracked and compared to
previous values sent to the hardware.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   7 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 3 files changed, 138 insertions(+), 131 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b9e9e8b02fb7..0cbe867ec375 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -295,13 +295,6 @@ struct amdgpu_display_funcs {
  uint16_t connector_object_id,
  struct amdgpu_hpd *hpd,
  struct amdgpu_router *router);
-   /* it is used to enter or exit into free sync mode */
-   int (*notify_freesync)(struct drm_device *dev, void *data,
-  struct drm_file *filp);
-   /* it is used to allow enablement of freesync mode */
-   int (*set_freesync_property)(struct drm_connector *connector,
-struct drm_property *property,
-uint64_t val);
 
 
 };
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 b0df6dc9a775..53eb3d16f75c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1809,72 +1809,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->freesync_enabled = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static 

[PATCH v7 3/5] drm: Document variable refresh properties

2018-11-08 Thread Nicholas Kazlauskas
These include the drm_connector 'vrr_capable' and the drm_crtc
'vrr_enabled' properties.

Signed-off-by: Nicholas Kazlauskas 
Cc: Harry Wentland 
Cc: Manasi Navare 
Cc: Pekka Paalanen 
Cc: Ville Syrjälä 
Cc: Michel Dänzer 
---
 Documentation/gpu/drm-kms.rst   |  7 
 drivers/gpu/drm/drm_connector.c | 68 +
 2 files changed, 75 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 4b1501b4835b..8da2a178cf85 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -575,6 +575,13 @@ Explicit Fencing Properties
 .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
:doc: explicit fencing properties
 
+
+Variable Refresh Properties
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+   :doc: Variable refresh properties
+
 Existing KMS Properties
 ---
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 49290060ab7b..0e4287461997 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1255,6 +1255,74 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * DOC: Variable refresh properties
+ *
+ * Variable refresh rate capable displays can dynamically adjust their
+ * refresh rate by extending the duration of their vertical front porch
+ * until page flip or timeout occurs. This can reduce or remove stuttering
+ * and latency in scenarios where the page flip does not align with the
+ * vblank interval.
+ *
+ * An example scenario would be an application flipping at a constant rate
+ * of 48Hz on a 60Hz display. The page flip will frequently miss the vblank
+ * interval and the same contents will be displayed twice. This can be
+ * observed as stuttering for content with motion.
+ *
+ * If variable refresh rate was active on a display that supported a
+ * variable refresh range from 35Hz to 60Hz no stuttering would be observable
+ * for the example scenario. The minimum supported variable refresh rate of
+ * 35Hz is below the page flip frequency and the vertical front porch can
+ * be extended until the page flip occurs. The vblank interval will be
+ * directly aligned to the page flip rate.
+ *
+ * Not all userspace content is suitable for use with variable refresh rate.
+ * Large and frequent changes in vertical front porch duration may worsen
+ * perceived stuttering for input sensitive applications.
+ *
+ * Panel brightness will also vary with vertical front porch duration. Some
+ * panels may have noticeable differences in brightness between the minimum
+ * vertical front porch duration and the maximum vertical front porch duration.
+ * Large and frequent changes in vertical front porch duration may produce
+ * observable flickering for such panels.
+ *
+ * Userspace control for variable refresh rate is supported via properties
+ * on the _connector and _crtc objects.
+ *
+ * "vrr_capable":
+ * Optional _connector boolean property that drivers should attach
+ * with drm_connector_attach_vrr_capable_property() on connectors that
+ * could support variable refresh rates. Drivers should update the
+ * property value by calling drm_connector_set_vrr_capable_property().
+ *
+ * Absence of the property should indicate absence of support.
+ *
+ * "vrr_enabled":
+ * Default _crtc boolean property that notifies the driver that the
+ * content on the CRTC is suitable for variable refresh rate presentation.
+ * The driver will take this property as a hint to enable variable
+ * refresh rate support if the receiver supports it, ie. if the
+ * "vrr_capable" property is true on the _connector object. The
+ * vertical front porch duration will be extended until page-flip or
+ * timeout when enabled.
+ *
+ * The minimum vertical front porch duration is defined as the vertical
+ * front porch duration for the current mode.
+ *
+ * The maximum vertical front porch duration is greater than or equal to
+ * the minimum vertical front porch duration. The duration is derived
+ * from the minimum supported variable refresh rate for the connector.
+ *
+ * The driver may place further restrictions within these minimum
+ * and maximum bounds.
+ *
+ * The semantics for the vertical blank timestamp differ when
+ * variable refresh rate is active. The vertical blank timestamp
+ * is defined to be an estimate using the current mode's fixed
+ * refresh rate timings. The semantics for the page-flip event
+ * timestamp remain the same.
+ */
+
 /**
  * drm_connector_attach_vrr_capable_property - creates the
  * vrr_capable property
-- 
2.19.1

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


[PATCH v6 0/5] A DRM API for adaptive sync and variable refresh rate support

2018-11-06 Thread Nicholas Kazlauskas
via the Present extension 
to xf86-video-amdgpu for the entire Screen. Some compositors may interfere with 
this if they are unable to unredirect the window.

Full implementation details for these changes can be reviewed in their 
respective mailing lists and the xf86-video-amdgpu GitLab.

=== Previous discussions ===

These patches are based upon feedback from previous threads on the subject. 
These are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/189404.htm
https://lists.freedesktop.org/archives/dri-devel/2018-September/190910.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192211.html
https://lists.freedesktop.org/archives/dri-devel/2018-October/192874.html

Nicholas Kazlauskas (5):
  drm: Add vrr_capable property to the drm connector
  drm: Add vrr_enabled property to drm CRTC
  drm: Document variable refresh properties
  drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal
  drm/amdgpu: Set FreeSync state using drm VRR properties

 Documentation/gpu/drm-kms.rst |   7 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |   7 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   7 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 drivers/gpu/drm/drm_atomic_uapi.c |   4 +
 drivers/gpu/drm/drm_connector.c   | 110 
 drivers/gpu/drm/drm_crtc.c|   2 +
 drivers/gpu/drm/drm_mode_config.c |   6 +
 include/drm/drm_connector.h   |  15 ++
 include/drm/drm_crtc.h|   9 +
 include/drm/drm_mode_config.h |   5 +
 12 files changed, 302 insertions(+), 132 deletions(-)

-- 
2.19.1

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


[PATCH v6 4/5] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

2018-11-06 Thread Nicholas Kazlauskas
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 timestap from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas 
Cc: Michel Dänzer 
Cc: Harry Wentland 
---
 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 6748cd7fc129..cb331319f225 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -850,7 +850,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 v6 5/5] drm/amdgpu: Set FreeSync state using drm VRR properties

2018-11-06 Thread Nicholas Kazlauskas
Support for AMDGPU specific FreeSync properties and ioctls are dropped
from amdgpu_dm in favor of supporting drm variable refresh rate
properties.

The notify_freesync and set_freesync_property functions are dropped
from amdgpu_display_funcs.

The drm vrr_capable property is now attached to any DP/HDMI connector.
Its value is updated accordingly to the connector's FreeSync capabiltiy.

The freesync_enable logic and ioctl control has has been dropped in
favor of utilizing the vrr_enabled on the drm CRTC. This allows for more
fine grained atomic control over which CRTCs should support variable
refresh rate.

To handle state changes for vrr_enabled it was easiest to drop the
forced modeset on freesync_enabled change. This patch now performs the
required stream updates when planes are flipped.

This is done for a few reasons:

(1) VRR stream updates can be done in the fast update path

(2) amdgpu_dm_atomic_check would need to be hacked apart to check
desired variable refresh state and capability before the CRTC
disable pass.

(3) Performing VRR stream updates on-flip is needed for enabling BTR
support.

VRR packets and timing adjustments are now tracked and compared to
previous values sent to the hardware.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   7 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 255 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   7 +-
 3 files changed, 138 insertions(+), 131 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b9e9e8b02fb7..0cbe867ec375 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -295,13 +295,6 @@ struct amdgpu_display_funcs {
  uint16_t connector_object_id,
  struct amdgpu_hpd *hpd,
  struct amdgpu_router *router);
-   /* it is used to enter or exit into free sync mode */
-   int (*notify_freesync)(struct drm_device *dev, void *data,
-  struct drm_file *filp);
-   /* it is used to allow enablement of freesync mode */
-   int (*set_freesync_property)(struct drm_connector *connector,
-struct drm_property *property,
-uint64_t val);
 
 
 };
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 b0df6dc9a775..53eb3d16f75c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1809,72 +1809,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->freesync_enabled = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static 

[PATCH v6 3/5] drm: Document variable refresh properties

2018-11-06 Thread Nicholas Kazlauskas
These include the drm_connector 'vrr_capable' and the drm_crtc
'vrr_enabled' properties.

Signed-off-by: Nicholas Kazlauskas 
Cc: Harry Wentland 
Cc: Manasi Navare 
Cc: Pekka Paalanen 
Cc: Ville Syrjälä 
Cc: Michel Dänzer 
---
 Documentation/gpu/drm-kms.rst   |  7 
 drivers/gpu/drm/drm_connector.c | 61 +
 2 files changed, 68 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 4b1501b4835b..8da2a178cf85 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -575,6 +575,13 @@ Explicit Fencing Properties
 .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
:doc: explicit fencing properties
 
+
+Variable Refresh Properties
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+   :doc: Variable refresh properties
+
 Existing KMS Properties
 ---
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 49290060ab7b..a6adf5450db3 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1255,6 +1255,67 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * DOC: Variable refresh properties
+ *
+ * Variable refresh rate capable displays can dynamically adjust their
+ * refresh rate by extending the duration of their vertical porch until
+ * page flip or timeout occurs. This can reduce or remove stuttering
+ * and latency in scenarios where the page flip does not align with the
+ * vblank interval.
+ *
+ * An example scenario would be an application flipping at a constant rate
+ * of 48Hz on a 60Hz display. The page flip will frequently miss the vblank
+ * interval and the same contents will be displayed twice. This can be
+ * observed as stuttering for content with motion.
+ *
+ * If variable refresh rate was active on a display that supported a
+ * variable refresh range from 35Hz to 60Hz no stuttering would be observable
+ * for the example scenario. The minimum supported variable refresh rate of
+ * 35Hz is below the page flip frequency and the vertical front porch can
+ * be extended until the page flip occurs. The vblank interval will be
+ * directly aligned to the page flip rate.
+ *
+ * Userspace control for variable refresh rate is supported via properties
+ * on the _connector and _crtc objects.
+ *
+ * "vrr_capable":
+ * Optional _connector boolean property that drivers should attach
+ * with drm_connector_attach_vrr_capable_property() on connectors that
+ * could support variable refresh rates. Drivers should update the
+ * property value by calling drm_connector_set_vrr_capable_property().
+ *
+ * Absence of the property should indicate absence of support.
+ *
+ * "vrr_enabled":
+ * Default _crtc boolean property that notifies the driver that the
+ * content on the CRTC is suitable for variable refresh rate presentation.
+ * The driver will take this property as a hint to enable variable
+ * refresh rate support if the receiver supports it, ie. if the
+ * "vrr_capable" property is true on the _connector object. The
+ * veritcal front porch duration will be extended until page-flip or
+ * timeout when enabled.
+ *
+ * The minimum vertical front porch duration is defined as the vertical
+ * front porch duration for the current mode.
+ *
+ * The maximum vertical front porch duration is greater than or equal to
+ * the minimum vertical front porch duration. The duration is derived
+ * from the minimum supported variable refresh rate for the connector.
+ *
+ * The driver may place further restrictions within these minimum
+ * and maximum bounds.
+ *
+ * Some displays may exhibit noticeable differences in brightness when
+ * varying vertical front porch duration.
+ *
+ * The semantics for the vertical blank timestamp differ when
+ * variable refresh rate is active. The vertical blank timestamp
+ * is defined to be an estimate using the current mode's fixed
+ * refresh rate timings. The semantics for the page-flip event
+ * timestamp remain the same.
+ */
+
 /**
  * drm_connector_attach_vrr_capable_property - creates the
  * vrr_capable property
-- 
2.19.1

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


[PATCH v6 1/5] drm: Add vrr_capable property to the drm connector

2018-11-06 Thread Nicholas Kazlauskas
Modern display hardware is capable of supporting variable refresh rates.
This patch introduces the "vrr_capable" property on the connector to
allow userspace to query support for variable refresh rates.

Atomic drivers should attach this property to connectors that are
capable of driving variable refresh rates using
drm_connector_attach_vrr_capable_property().

The value should be updated based on driver and hardware capabiltiy
by using drm_connector_set_vrr_capable_property().

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Manasi Navare 
Reviewed-by: Harry Wentland 
---
 drivers/gpu/drm/drm_connector.c | 49 +
 include/drm/drm_connector.h | 15 ++
 2 files changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 4943cef178be..49290060ab7b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1255,6 +1255,37 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_vrr_capable_property - creates the
+ * vrr_capable property
+ * @connector: connector to create the vrr_capable property on.
+ *
+ * This is used by atomic drivers to add support for querying
+ * variable refresh rate capability for a connector.
+ *
+ * Returns:
+ * Zero on success, negative errono on failure.
+ */
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->vrr_capable_property) {
+   prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
+   "vrr_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->vrr_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
@@ -1583,6 +1614,24 @@ void drm_connector_set_link_status_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_set_link_status_property);
 
+/**
+ * drm_connector_set_vrr_capable_property - sets the variable refresh rate
+ * capable property for a connector
+ * @connector: drm connector
+ * @capable: True if the connector is variable refresh rate capable
+ *
+ * Should be used by atomic drivers to update the indicated support for
+ * variable refresh rate over a connector.
+ */
+void drm_connector_set_vrr_capable_property(
+   struct drm_connector *connector, bool capable)
+{
+   drm_object_property_set_value(>base,
+ connector->vrr_capable_property,
+ capable);
+}
+EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
+
 /**
  * drm_connector_init_panel_orientation_property -
  * initialize the connecters panel_orientation property
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 9ccad6b062f2..4e6befff153b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -959,6 +959,17 @@ struct drm_connector {
 */
struct drm_property *scaling_mode_property;
 
+   /**
+* @vrr_capable_property: Optional property to help userspace
+* query hardware support for variable refresh rate on a connector.
+* connector. Drivers can add the property to a connector by
+* calling drm_connector_attach_vrr_capable_property().
+*
+* This should be updated only by calling
+* drm_connector_set_vrr_capable_property().
+*/
+   struct drm_property *vrr_capable_property;
+
/**
 * @content_protection_property: DRM ENUM property for content
 * protection. See drm_connector_attach_content_protection_property().
@@ -1250,6 +1261,8 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev);
 int drm_connector_attach_content_type_property(struct drm_connector *dev);
 int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
   u32 scaling_mode_mask);
+int drm_connector_attach_vrr_capable_property(
+   struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
@@ -1266,6 +1279,8 @@ int drm_connector_update_edid_property(struct 
drm_connector *connector,
   const struct edid *edid);
 void drm_connector_set_link_status_property(struct drm_connector *connector,
  

[PATCH v6 2/5] drm: Add vrr_enabled property to drm CRTC

2018-11-06 Thread Nicholas Kazlauskas
This patch introduces the 'vrr_enabled' CRTC property to allow
dynamic control over variable refresh rate support for a CRTC.

This property should be treated like a content hint to the driver -
if the hardware or driver is not capable of driving variable refresh
timings then this is not considered an error.

Capability for variable refresh rate support should be determined
by querying the vrr_capable drm connector property.

It is worth noting that while the property is intended for atomic use
it isn't filtered from legacy userspace queries. This allows for Xorg
userspace drivers to implement support.

Signed-off-by: Nicholas Kazlauskas 
Reviewed-by: Harry Wentland 
Cc: Manasi Navare 
---
 drivers/gpu/drm/drm_atomic_uapi.c | 4 
 drivers/gpu/drm/drm_crtc.c| 2 ++
 drivers/gpu/drm/drm_mode_config.c | 6 ++
 include/drm/drm_crtc.h| 9 +
 include/drm/drm_mode_config.h | 5 +
 5 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d5b7f315098c..eec396a57b88 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -433,6 +433,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
drm_property_blob_put(mode);
return ret;
+   } else if (property == config->prop_vrr_enabled) {
+   state->vrr_enabled = val;
} else if (property == config->degamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
@@ -491,6 +493,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->active;
else if (property == config->prop_mode_id)
*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+   else if (property == config->prop_vrr_enabled)
+   *val = state->vrr_enabled;
else if (property == config->degamma_lut_property)
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 268a182ae189..6f8ddfcfaba5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -340,6 +340,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
drm_object_attach_property(>base, config->prop_mode_id, 
0);
drm_object_attach_property(>base,
   config->prop_out_fence_ptr, 0);
+   drm_object_attach_property(>base,
+  config->prop_vrr_enabled, 0);
}
 
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index ee80788f2c40..5670c67f28d4 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -310,6 +310,12 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
 
+   prop = drm_property_create_bool(dev, 0,
+   "VRR_ENABLED");
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.prop_vrr_enabled = prop;
+
prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b21437bc95bf..39c3900aab3c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -290,6 +290,15 @@ struct drm_crtc_state {
 */
u32 pageflip_flags;
 
+   /**
+* @vrr_enabled:
+*
+* Indicates if variable refresh rate should be enabled for the CRTC.
+* Support for the requested vrr state will depend on driver and
+* hardware capabiltiy - lacking support is not treated as failure.
+*/
+   bool vrr_enabled;
+
/**
 * @event:
 *
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 928e4172a0bb..49f2fcfdb5fc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -639,6 +639,11 @@ struct drm_mode_config {
 * connectors must be of and active must be set to disabled, too.
 */
struct drm_property *prop_mode_id;
+   /**
+* @prop_vrr_enabled: Default atomic CRTC property to indicate
+* whether variable refresh rate should be enabled on the CRTC.
+*/
+   struct drm_property *prop_vrr_enabled;
 
/**
 * @dvi_i_subconnector_property: Optional DVI-I property to
-- 
2.19.1

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


[PATCH 1/2] drm/amdgpu: Add "max_bpc" connector property

2018-11-07 Thread Nicholas Kazlauskas
[Why]
Many panels support more than 8bpc but some modes are unavailable while
running at greater than 8bpc due to DP/HDMI bandwidth constraints.

Support for more than 8bpc was added recently in the driver but it's
defaults to the maximum supported bpc - locking out these modes.

This should be a user configurable option such that the user can select
what bpc configuration they would like.

[How]
Introduce the "max_bpc" connector property so the user can limit the
maximum bpc for the panel. It ranges from 8 to 16.

This doesn't directly set the preferred bpc for the panel but this
convetion is already in use for other drivers.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 5 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h| 2 ++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 7d6a36bca9dd..83dadf5b85e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -626,6 +626,11 @@ int amdgpu_display_modeset_create_props(struct 
amdgpu_device *adev)
 "dither",
 amdgpu_dither_enum_list, sz);
 
+   adev->mode_info.max_bpc_property =
+   drm_property_create_range(adev->ddev, 0, "max_bpc", 8, 16);
+   if (!adev->mode_info.max_bpc_property)
+   return -ENOMEM;
+
if (amdgpu_device_has_dc_support(adev)) {
adev->mode_info.freesync_property =
drm_property_create_bool(adev->ddev, 0, "freesync");
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1627dd3413c7..c39af5d79608 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -338,6 +338,8 @@ struct amdgpu_mode_info {
struct drm_property *audio_property;
/* FMT dithering */
struct drm_property *dither_property;
+   /* maximum number of bits per channel for monitor color */
+   struct drm_property *max_bpc_property;
/* it is used to allow enablement of freesync mode */
struct drm_property *freesync_property;
/* it is used to know about display capability of freesync mode */
-- 
2.17.1

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


[PATCH 2/2] drm/amd/display: Support "max_bpc" connector property

2018-11-07 Thread Nicholas Kazlauskas
[Why]
Many panels support more than 8bpc but some modes are unavailable while
running at greater than 8bpc due to DP/HDMI bandwidth constraints.

Support for more than 8bpc was added recently in the driver but it's
defaults to the maximum supported bpc - locking out these modes.

This should be a user configurable option such that the user can select
what bpc configuration they would like.

[How]
Add support for getting and setting the property on the connector
in amdgpu_dm.

The maximum bpc is then limited by the value set by the user. The
default value is the lowest in the range, 8bpc. This was the old
default before the range was uncapped.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c440d967db57..6184c5bc52e3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2417,8 +2417,14 @@ static void update_stream_scaling_settings(const struct 
drm_display_mode *mode,
 static enum dc_color_depth
 convert_color_depth_from_display_info(const struct drm_connector *connector)
 {
+   struct dm_connector_state *dm_conn_state =
+   to_dm_connector_state(connector->state);
uint32_t bpc = connector->display_info.bpc;
 
+   if (dm_conn_state && bpc > dm_conn_state->max_bpc)
+   /* Round down to nearest even number. */
+   bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1);
+
switch (bpc) {
case 0:
/*
@@ -3001,6 +3007,9 @@ int amdgpu_dm_connector_atomic_set_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
dm_new_state->underscan_enable = val;
ret = 0;
+   } else if (property == adev->mode_info.max_bpc_property) {
+   dm_new_state->max_bpc = val;
+   ret = 0;
} else if (property == adev->mode_info.freesync_property) {
dm_new_state->freesync_enable = val;
ret = 0;
@@ -3049,6 +3058,9 @@ int amdgpu_dm_connector_atomic_get_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
*val = dm_state->underscan_enable;
ret = 0;
+   } else if (property == adev->mode_info.max_bpc_property) {
+   *val = dm_state->max_bpc;
+   ret = 0;
} else if (property == adev->mode_info.freesync_property) {
*val = dm_state->freesync_enable;
ret = 0;
@@ -3864,6 +3876,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(>base.base,
adev->mode_info.underscan_vborder_property,
0);
+   drm_object_attach_property(>base.base,
+   adev->mode_info.max_bpc_property,
+   0);
 
if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 23f2d05cf07e..afcb9842bb45 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -252,6 +252,7 @@ struct dm_connector_state {
enum amdgpu_rmx_type scaling;
uint8_t underscan_vborder;
uint8_t underscan_hborder;
+   uint8_t max_bpc;
bool underscan_enable;
bool freesync_enable;
bool freesync_capable;
-- 
2.17.1

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


[PATCH v2 3/3] drm/amd/display: Set FreeSync state using DRM VRR properties

2018-09-24 Thread Nicholas Kazlauskas
The AMDGPU specific FreeSync properties and IOCTLs are dropped
from amdgpu_dm in favor of the DRM variable refresh properties.

The AMDGPU connector properties freesync_capable and freesync_enabled
are mostly direct mappings to the DRM variable_refresh_capable and
variable_refresh_enabled.

The AMDGPU CRTC freesync_enabled property requires special care to
handle correctly. The DRM variable_refresh property is a content hint
to the driver which is independent from actual hardware variable
refresh capability and user configuration.

To handle changes with this property it was easier to drop the forced
modeset on variable refresh change. This patch now performs the required
stream updates when planes are attached *or* flipped.

This is done for a few reasons:

(1) VRR stream updates can be done in the fast update path

(2) amdgpu_dm_atomic_check would have had to been hacked apart to check
desired variable refresh state and capability before the CRTC
disable pass.

(3) Performing VRR stream updates on-flip is needed for enabling BTR
support.

FreeSync state on the stream is now tracked and compared to the previous
packet sent to the hardware.

It's worth noting that the current implementation treats
variable_refresh_enabled as a strict requirement for sending
the VRR enable *or* disable packet.

Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 232 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   6 +-
 2 files changed, 121 insertions(+), 117 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 6c849e055038..0fddc2e66f49 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1683,72 +1683,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->freesync_enabled = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static const struct amdgpu_display_funcs dm_display_funcs = {
.bandwidth_update = dm_bandwidth_update, /* called unconditionally */
@@ -1762,7 +1696,6 @@ static const struct amdgpu_display_funcs dm_display_funcs 
= {
dm_crtc_get_scanoutpos,/* called unconditionally */
.add_encoder = NULL, /* VBIOS parsing. DAL does it. */
.add_connector = NULL, /* VBIOS parsing. DAL does it. */
-   .notify_freesync = amdgpu_notify_freesync,
 
 };
 
@@ -2645,7 +2578,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
 
update_stream_signal(stream);
 
-   if (dm_state && dm_state->freesync_capable)
+   if (dm_state && dm_state->base.variable_refresh_capable)
stream->ignore_msa_timing_param = true;
 finish:
if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL)
@@ -2713,9 +2646,10 

[PATCH v2 2/3] drm: Add variable refresh property to DRM CRTC

2018-09-24 Thread Nicholas Kazlauskas
Variable refresh rate algorithms have typically been enabled only
when the display is covered by a single source of content.

This patch introduces a new default CRTC property that helps
hint to the driver when the CRTC composition is suitable for variable
refresh rate algorithms. Userspace can set this property dynamically
as the composition changes.

Whether the variable refresh rate algorithms are active will still
depend on the CRTC being suitable and the connector being capable
and enabled by the user for variable refresh rate support.

It is worth noting that while the property is atomic it isn't filtered
from legacy userspace queries. This allows for Xorg userspace drivers
to implement support in non-atomic setups.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic_helper.c |  1 +
 drivers/gpu/drm/drm_atomic_uapi.c   |  6 ++
 drivers/gpu/drm/drm_crtc.c  |  2 ++
 drivers/gpu/drm/drm_mode_config.c   |  6 ++
 include/drm/drm_crtc.h  | 13 +
 include/drm/drm_mode_config.h   |  8 
 6 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 3cf1aa132778..b768d397a811 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3473,6 +3473,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct 
drm_crtc *crtc,
state->planes_changed = false;
state->connectors_changed = false;
state->color_mgmt_changed = false;
+   state->variable_refresh_changed = false;
state->zpos_changed = false;
state->commit = NULL;
state->event = NULL;
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 0bb27a24a55c..32a4cf8a01c3 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -433,6 +433,10 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
drm_property_blob_put(mode);
return ret;
+   } else if (property == config->prop_variable_refresh) {
+   if (state->variable_refresh != val)
+   state->variable_refresh_changed = true;
+   state->variable_refresh = val;
} else if (property == config->degamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
@@ -491,6 +495,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->active;
else if (property == config->prop_mode_id)
*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+   else if (property == config->prop_variable_refresh)
+   *val = state->variable_refresh;
else if (property == config->degamma_lut_property)
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5f488aa80bcd..ca33d6fb90ac 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -340,6 +340,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
drm_object_attach_property(>base, config->prop_mode_id, 
0);
drm_object_attach_property(>base,
   config->prop_out_fence_ptr, 0);
+   drm_object_attach_property(>base,
+  config->prop_variable_refresh, 0);
}
 
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index ee80788f2c40..1287c161d65d 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -310,6 +310,12 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
 
+   prop = drm_property_create_bool(dev, 0,
+   "VARIABLE_REFRESH");
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.prop_variable_refresh = prop;
+
prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b21437bc95bf..32b77f18ce6d 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -168,6 +168,12 @@ struct drm_crtc_state {
 * drivers to steer the atomic commit control flow.
 */
bool color_mgmt_changed : 1;
+   /**
+* @variable_refresh_changed: Variable refresh support has changed
+* on the CRTC. Used by the atomic helpers and drivers to steer the
+*

[PATCH v2 0/3] A DRM API for adaptive sync and variable refresh rate support

2018-09-24 Thread Nicholas Kazlauskas
These patches are part of a proposed new interface for supporting variable 
refresh rate via DRM properties.

=== Changes from v1 ===

For drm:

* The variable_refresh_capable property is now flagged as 
DRM_MODE_PROP_IMMUTABLE

For drm/gpu/amd/display:

* Patches no longer pull in IOCTL/FreeSync refactoring code
* FreeSync enable/disable behavior has been modified to reflect changes in 
userspace behavior from xf86-video-amdgpu and mesa

=== Adaptive sync and variable refresh rate ===

Adaptive sync is part of the DisplayPort spec and allows for graphics adapters 
to drive displays with varying frame timings.

Variable refresh rate (VRR) is essentially the same, but defined for HDMI.

=== Use cases for variable refresh rate ===

Variable frame (flip) timings don't align well with fixed refresh rate 
displays. This results in stuttering, tearing and/or input lag. By adjusting 
the display refresh rate dynamically these issues can be reduced or eliminated.

However, not all content is suitable for dynamic refresh adaptation. Content 
that is flipped infrequently or at random intervals tends to fair poorly. 
Multiple clients trying to flip under the same screen can similarly interfere 
with prediction.

Userland needs a way to let the driver know when the content on the screen is 
suitable for variable refresh rate and if the user wishes to have the feature 
enabled.

=== DRM API to support variable refresh rates ===

This patch introduces a new API via atomic properties on the DRM connector and 
CRTC.

The connector has two new optional properties:

* bool variable_refresh_capable - set by the driver if the hardware is capable 
of supporting variable refresh tech

* bool variable_refresh_enabled - set by the user to enable variable refresh 
adjustment over the connector

The CRTC has one additional default property:

* bool variable_refresh - a content hint to the driver specifying that the CRTC 
contents are suitable for variable refresh adjustment

== Overview for DRM driver developers ===

Driver developers can attach the optional connector properties via 
drm_connector_attach_variable_refresh_properties on connectors that support 
variable refresh (typically DP or HDMI).

The variable_refresh_capable property should be managed as the output on the 
connector changes. The property is read only from userspace.

The variable_refresh_enabled property is intended to be a property controlled 
by userland as a global on/off switch for variable refresh technology. It 
should be checked before enabling variable refresh rate.

=== Overview for Userland developers ==

The variable_refresh property on the CRTC should be set to true when the CRTCs 
are suitable for variable refresh rate. In practice this is probably an 
application like a game - a single window that covers the whole CRTC surface 
and is the only client issuing flips.

To demonstrate the suitability of the API for variable refresh and dynamic 
adaptation there are additional patches using this API that implement adaptive 
variable refresh across kernel and userland projects:

* DRM (dri-devel)
* amdgpu DRM kernel driver (amd-gfx)
* xf86-video-amdgpu (amd-gfx)
* mesa (mesa-dev)

These patches enable adaptive variable refresh on X for AMD hardware provided 
that the user sets the variable_refresh_enabled property to true on supported 
connectors (ie. using xrandr --set-prop).

The patches have been tested as working on upstream userland with the GNOME 
desktop environment under a single monitor setup. They also work on KDE in 
single monitor setup if the compositor is disabled.

The patches require that the application window can issue screen flips via the 
Present extension to xf86-video-amdgpu. Due to Present extension limitations 
some desktop environments and multi-monitor setups are currently not compatible.

Full implementation details for these changes can be reviewed in their 
respective mailing lists.

=== Previous discussions ===

These patches are based upon feedback from patches and feedback from two 
previous threads on the subject which are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html
https://lists.freedesktop.org/archives/dri-devel/2018-September/189404.html

Nicholas Kazlauskas

Nicholas Kazlauskas (3):
  drm: Add variable refresh rate properties to connector
  drm: Add variable refresh property to DRM CRTC
  drm/amd/display: Set FreeSync state using DRM VRR properties

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 232 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   6 +-
 drivers/gpu/drm/drm_atomic_helper.c   |   1 +
 drivers/gpu/drm/drm_atomic_uapi.c |  12 +
 drivers/gpu/drm/drm_connector.c   |  35 +++
 drivers/gpu/drm/drm_crtc.c|   2 +
 drivers/gpu/drm/drm_mode_config.c |   6 +
 include/drm/drm_connector.h

[PATCH v2 1/3] drm: Add variable refresh rate properties to connector

2018-09-24 Thread Nicholas Kazlauskas
Modern display hardware is capable of supporting variable refresh rates
and adaptive sync technologies. The properties for querying and
controlling these features should be exposed on the DRM connector.

This patch introduces two new properties for variable refresh rate
support:

- variable_refresh_capable
- variable_refresh_enabled

These are optional properties that can be added to a DRM connector
dynamically by using drm_connector_attach_variable_refresh_properties.

DRM drivers should set variable_refresh_capable as applicable for
their hardware. The property variable_refresh_enabled is a userspace
controlled option.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic_uapi.c |  6 ++
 drivers/gpu/drm/drm_connector.c   | 35 +++
 include/drm/drm_connector.h   | 27 
 3 files changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d5b7f315098c..0bb27a24a55c 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -723,6 +723,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->content_type = val;
} else if (property == connector->scaling_mode_property) {
state->scaling_mode = val;
+   } else if (property == connector->variable_refresh_enabled_property) {
+   state->variable_refresh_enabled = val;
} else if (property == connector->content_protection_property) {
if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
@@ -797,6 +799,10 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->content_type;
} else if (property == connector->scaling_mode_property) {
*val = state->scaling_mode;
+   } else if (property == connector->variable_refresh_capable_property) {
+   *val = state->variable_refresh_capable;
+   } else if (property == connector->variable_refresh_enabled_property) {
+   *val = state->variable_refresh_enabled;
} else if (property == connector->content_protection_property) {
*val = state->content_protection;
} else if (property == config->writeback_fb_id_property) {
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1e40e5decbe9..fc1732639bd3 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1254,6 +1254,41 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_variable_refresh_properties - creates and attaches
+ * properties for connectors that support adaptive refresh
+ * @connector: connector to create adaptive refresh properties on
+ */
+int drm_connector_attach_variable_refresh_properties(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->variable_refresh_capable_property) {
+   prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
+   "variable_refresh_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->variable_refresh_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   if (!connector->variable_refresh_enabled_property) {
+   prop = drm_property_create_bool(dev, 0,
+   "variable_refresh_enabled");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->variable_refresh_enabled_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_variable_refresh_properties);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 91a877fa00cb..e2c26842bd50 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -449,6 +449,18 @@ struct drm_connector_state {
 */
unsigned int content_protection;
 
+   /**
+* @variable_refresh_enabled: Connector property used to check
+* if variable refresh is supported on the device.
+*/
+   bool variable_refresh_capable;
+
+   /**
+* @variable_refresh_enabled: Connector property used to check
+* if variable refresh is enabled.
+*/
+   bool variable_refresh_enabled;
+
/**
 * @writeback_job: Writeback job for writeback connec

[PATCH] drm/amd/display: Set requested plane state DCC params for GFX9

2019-01-02 Thread Nicholas Kazlauskas
[Why]
Hardware support for Delta Color Compression (DCC) decompression is
available in DC for GFX9 but there's no way for userspace to enable
the feature.

Enabling the feature can provide improved GFX performance and
power savings in many situations.

[How]
The GFX9 DCC parameters are passed to amdgpu_dm from AMDGPU via the
amdgpu_bo tiling_flags. The plane capability is queried and the
parameters are set accordingly.

The DCC address is given via a 256 byte aligned offset on the
framebuffer address. The DCC address is updated whenever the buffer
address changes.

Cc: Marek Olšák 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 90 ++-
 1 file changed, 88 insertions(+), 2 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 306540c36616..4839d2dc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2356,6 +2356,68 @@ static int get_fb_info(const struct amdgpu_framebuffer 
*amdgpu_fb,
return r;
 }
 
+static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
+{
+   uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
+
+   return offset ? (address + offset * 256) : 0;
+}
+
+static bool fill_plane_dcc_attributes(struct amdgpu_device *adev,
+ const struct amdgpu_framebuffer *afb,
+ struct dc_plane_state *plane_state,
+ uint64_t info)
+{
+   struct dc *dc = adev->dm.dc;
+   struct dc_dcc_surface_param input = {0};
+   struct dc_surface_dcc_cap output = {0};
+   uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
+   uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
+   uint64_t dcc_address;
+
+   if (!offset)
+   return false;
+
+   if (!dc->cap_funcs.get_dcc_compression_cap)
+   return false;
+
+   input.format = plane_state->format;
+   input.surface_size.width =
+   plane_state->plane_size.grph.surface_size.width;
+   input.surface_size.height =
+   plane_state->plane_size.grph.surface_size.height;
+   input.swizzle_mode = plane_state->tiling_info.gfx9.swizzle;
+
+   if (plane_state->rotation == ROTATION_ANGLE_0 ||
+   plane_state->rotation == ROTATION_ANGLE_180)
+   input.scan = SCAN_DIRECTION_HORIZONTAL;
+   else if (plane_state->rotation == ROTATION_ANGLE_90 ||
+plane_state->rotation == ROTATION_ANGLE_270)
+   input.scan = SCAN_DIRECTION_VERTICAL;
+
+   if (!dc->cap_funcs.get_dcc_compression_cap(dc, , ))
+   return false;
+
+   if (!output.capable)
+   return false;
+
+   if (i64b == 0 && output.grph.rgb.independent_64b_blks != 0)
+   return false;
+
+   plane_state->dcc.enable = 1;
+   plane_state->dcc.grph.meta_pitch =
+   AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
+   plane_state->dcc.grph.independent_64b_blks = i64b;
+
+   dcc_address = get_dcc_address(afb->address, info);
+   plane_state->address.grph.meta_addr.low_part =
+   lower_32_bits(dcc_address);
+   plane_state->address.grph.meta_addr.high_part =
+   upper_32_bits(dcc_address);
+
+   return true;
+}
+
 static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
 struct dc_plane_state *plane_state,
 const struct amdgpu_framebuffer 
*amdgpu_fb)
@@ -2408,6 +2470,10 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
return -EINVAL;
}
 
+   memset(_state->address, 0, sizeof(plane_state->address));
+   memset(_state->tiling_info, 0, sizeof(plane_state->tiling_info));
+   memset(_state->dcc, 0, sizeof(plane_state->dcc));
+
if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
plane_state->address.type = PLN_ADDR_TYPE_GRAPHICS;
plane_state->plane_size.grph.surface_size.x = 0;
@@ -2439,8 +2505,6 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
plane_state->color_space = COLOR_SPACE_YCBCR709;
}
 
-   memset(_state->tiling_info, 0, sizeof(plane_state->tiling_info));
-
/* Fill GFX8 params */
if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 
DC_ARRAY_2D_TILED_THIN1) {
unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
@@ -2489,6 +2553,9 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
plane_state->tiling_info.gfx9.swizzle =
AMDGPU_T

[PATCH] drm/amd/display: Don't cleanup new cursor fb in fast cursor update

2018-12-14 Thread Nicholas Kazlauskas
[Why]
The behavior of dm_plane_helper_cleanup_fb differs depending on
whether the commit was asynchronous or not. When it's called from
amdgpu_dm_atomic_commit_tail during a typical atomic commit the
plane state has been swapped so it calls cleanup_fb on the old plane
state.

However, in the asynchronous commit codepath the call to
drm_atomic_helper_commit also calls dm_plane_helper_cleanup_fb after
atomic_async_update has been called. Since the plane state has not
been swapped, the cleanup_fb call affects the new plane state with the
active fb.

The slow, full path is only ever used for the cursor update when the
cursor CRTC changes. If there was previously a fb in the state before
that had gone through the fast asynchronous path then cleanup_fb will
be called a second time on an fb that was previously unpinned/unref'd.

This results in a use after free on the next cursor update.

[How]
Regardless of whether this was intentional behavior in DRM or not,
the fix is to manually call cleanup_fb on the old plane state's fb.

Since the pointer to the old_plane_state is actually the current
plane->state in this function, a backup is needed. This has a minor
change to behavior for handle_cursor_update since it now correctly uses
the old state.

The next step is to prevent the cleanup_fb call from DRM from unpinning
the active new_state->fb. Setting new_state->fb to NULL would be
enough to handle this, but DRM has a warning in the
drm_atomic_helper_async_commit helper if
plane->state->fb != new_state->fb.

A new field was added (cursor_update) to dm_plane_state that's only
ever set to true during the fast path. If it's true, then cleanup_fb
doesn't unpin and unref the fb.

Cc: Leo Li 
Cc: Harry Wentland 
Cc: Michel Dänzer 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 17 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h   |  2 ++
 2 files changed, 15 insertions(+), 4 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 d01315965af0..b71c834a959d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3589,9 +3589,10 @@ static void dm_plane_helper_cleanup_fb(struct drm_plane 
*plane,
   struct drm_plane_state *old_state)
 {
struct amdgpu_bo *rbo;
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(old_state);
int r;
 
-   if (!old_state->fb)
+   if (!old_state->fb || dm_plane_state->cursor_update)
return;
 
rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
@@ -3638,8 +3639,8 @@ static int dm_plane_atomic_async_check(struct drm_plane 
*plane,
 static void dm_plane_atomic_async_update(struct drm_plane *plane,
 struct drm_plane_state *new_state)
 {
-   struct drm_plane_state *old_state =
-   drm_atomic_get_old_plane_state(new_state->state, plane);
+   struct drm_plane_state old_state = *plane->state;
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(new_state);
 
if (plane->state->fb != new_state->fb)
drm_atomic_set_fb_for_plane(plane->state, new_state->fb);
@@ -3653,7 +3654,15 @@ static void dm_plane_atomic_async_update(struct 
drm_plane *plane,
plane->state->crtc_w = new_state->crtc_w;
plane->state->crtc_h = new_state->crtc_h;
 
-   handle_cursor_update(plane, old_state);
+   handle_cursor_update(plane, _state);
+
+   /*
+* While DRM already takes care of drm_atomic_helper_cleanup_planes,
+* it does it on the wrong state (new_state instead of old_state).
+* This is a workaround for that behavior.
+*/
+   dm_plane_helper_cleanup_fb(plane, _state);
+   dm_plane_state->cursor_update = true;
 }
 
 static const struct drm_plane_helper_funcs dm_plane_helper_funcs = {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 25bb91ee80ba..ecac91036864 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -254,6 +254,8 @@ struct dc_plane_state;
 struct dm_plane_state {
struct drm_plane_state base;
struct dc_plane_state *dc_state;
+
+   bool cursor_update;
 };
 
 struct dm_crtc_state {
-- 
2.17.1

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


[PATCH] drm/amd/display: Fix cursor pos and hotspot calcs

2018-12-12 Thread Nicholas Kazlauskas
[Why]
The cursor calculations in amdgpu_dm incorrectly assume that the
cursor hotspot is always (0, 0) and don't respect the hot_x and hot_y
attributes that can be passed in via the drm_mode_cursor2_ioctl.

The DC hotspot parameters are also incorrectly used to offset the
cursor when it goes beyond the bounds of the screen instead of
being clamped.

[How]
Use the hot_x and hot_y attributes from the fb to directly fill in the
DC hotspot attributes.

Clamp the cursor position on the edges of the screen instead of using
the hotspot to offset it back in.

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +++
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 01badda14079..61f2eae0b67f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4266,7 +4266,6 @@ static int get_cursor_position(struct drm_plane *plane, 
struct drm_crtc *crtc,
 {
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
int x, y;
-   int xorigin = 0, yorigin = 0;
 
if (!crtc || !plane->state->fb) {
position->enable = false;
@@ -4284,24 +4283,18 @@ static int get_cursor_position(struct drm_plane *plane, 
struct drm_crtc *crtc,
return -EINVAL;
}
 
-   x = plane->state->crtc_x;
-   y = plane->state->crtc_y;
+   x = plane->state->crtc_x + plane->state->fb->hot_x;
+   y = plane->state->crtc_y + plane->state->fb->hot_y;
+
/* avivo cursor are offset into the total surface */
x += crtc->primary->state->src_x >> 16;
y += crtc->primary->state->src_y >> 16;
-   if (x < 0) {
-   xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
-   x = 0;
-   }
-   if (y < 0) {
-   yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1);
-   y = 0;
-   }
+
position->enable = true;
-   position->x = x;
-   position->y = y;
-   position->x_hotspot = xorigin;
-   position->y_hotspot = yorigin;
+   position->x = x >= 0 ? x : 0;
+   position->y = y >= 0 ? y : 0;
+   position->x_hotspot = plane->state->fb->hot_x;
+   position->y_hotspot = plane->state->fb->hot_y;
 
return 0;
 }
-- 
2.17.1

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


[PATCH] drm/amd/display: Skip fast cursor updates for fb changes

2018-12-14 Thread Nicholas Kazlauskas
[Why]
The behavior of drm_atomic_helper_cleanup_planes differs depending on
whether the commit was asynchronous or not. When it's called from
amdgpu_dm_atomic_commit_tail during a typical atomic commit the
plane state has been swapped so it calls cleanup_fb on the old plane
state.

However, in the asynchronous commit codepath the call to
drm_atomic_helper_commit also calls dm_plane_helper_cleanup_fb after
atomic_async_update has been called. Since the plane state is updated
in place and has not been swapped the cleanup_fb call affects the new
plane state.

This results in a use after free for the given sequence:

- Fast update, fb1 pin/ref, fb1 unpin/unref
- Fast update, fb2 pin/ref, fb2 unpin/unref
- Slow update, fb1 pin/ref, fb2 unpin/unref
- Fast update, fb2 pin/ref -> use after free. bug

[How]
Disallow framebuffer changes in the fast path. Since this includes
a NULL framebuffer, this means that only framebuffers that have
been previously pin+ref at least once will be used, preventing a
use after free.

This has a significant throughput reduction for cursor updates where
the framebuffer changes. For most desktop usage this isn't a problem,
but it does introduce performance regressions for two specific IGT
tests:

- cursor-vs-flip-toggle
- cursor-vs-flip-varying-size

Cc: Leo Li 
Cc: Harry Wentland 
Cc: Michel Dänzer 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d01315965af0..dc1eb9ec2c38 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3628,10 +3628,20 @@ static int dm_plane_atomic_check(struct drm_plane 
*plane,
 static int dm_plane_atomic_async_check(struct drm_plane *plane,
   struct drm_plane_state *new_plane_state)
 {
+   struct drm_plane_state *old_plane_state =
+   drm_atomic_get_old_plane_state(new_plane_state->state, plane);
+
/* Only support async updates on cursor planes. */
if (plane->type != DRM_PLANE_TYPE_CURSOR)
return -EINVAL;
 
+   /*
+* DRM calls prepare_fb and cleanup_fb on new_plane_state for
+* async commits so don't allow fb changes.
+*/
+   if (old_plane_state->fb != new_plane_state->fb)
+   return -EINVAL;
+
return 0;
 }
 
-- 
2.17.1

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


[PATCH] drm/amd/display: Fix NULL ptr deref for commit_planes_to_stream

2018-11-30 Thread Nicholas Kazlauskas
[Why]
With scaling, underscan and abm changes we can end up calling
commit_planes_to_stream in commit_tail. This call uses dm_state->context
which can be NULL if the commit was a fast update.

[How]
Use dc_state instead since that can't be NULL unless the system ran
out of memory.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108912
Fixes: e64abff2f133 ("drm/amd/display: Use private obj helpers for 
dm_atomic_state")

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 76b1aebdca0c..8ecd78657d43 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5011,7 +5011,7 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
status->plane_count,
dm_new_crtc_state,
to_dm_crtc_state(old_crtc_state),
-   dm_state->context))
+   dc_state))
dm_error("%s: Failed to update stream scaling!\n", 
__func__);
}
 
-- 
2.17.1

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


[PATCH] drm/amd/display: Add below the range support for FreeSync

2018-12-05 Thread Nicholas Kazlauskas
[Why]
When application flip-rate is below the minimum vrr refresh rate.

Variable refresh rate monitors extend the front porch duration until
flip or timeout occurs. For cases where the application flip-rate is

When the flip-rate is below the minimum supported variable refresh rate
range for the monitor the front porch wait will timeout and be
frequently misaligned resulting in stuttering and/or flickering.

The FreeSync module can still maintain a smooth and flicker free
image when the monitor has a refresh rate range such that the maximum
refresh > 2 * minimum refresh by utilizing low framerate compensation,
"below the range".

[How]
Hook up the pre-flip and post-flip handlers from the FreeSync module.
These adjust the minimum/maximum vrr range to duplicate frames
when appropriate by tracking flip timestamps.

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 79 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
 2 files changed, 62 insertions(+), 19 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 23d61570df17..e2de064426fc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -328,12 +328,29 @@ static void dm_crtc_high_irq(void *interrupt_params)
struct common_irq_params *irq_params = interrupt_params;
struct amdgpu_device *adev = irq_params->adev;
struct amdgpu_crtc *acrtc;
+   struct dm_crtc_state *acrtc_state;
 
acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - 
IRQ_TYPE_VBLANK);
 
if (acrtc) {
drm_crtc_handle_vblank(>base);
amdgpu_dm_crtc_handle_crc_irq(>base);
+
+   acrtc_state = to_dm_crtc_state(acrtc->base.state);
+
+   if (acrtc_state->stream &&
+   acrtc_state->vrr_params.supported &&
+   acrtc_state->freesync_config.state == 
VRR_STATE_ACTIVE_VARIABLE) {
+   mod_freesync_handle_v_update(
+   adev->dm.freesync_module,
+   acrtc_state->stream,
+   _state->vrr_params);
+
+   dc_stream_adjust_vmin_vmax(
+   adev->dm.dc,
+   acrtc_state->stream,
+   _state->vrr_params.adjust);
+   }
}
 }
 
@@ -3001,7 +3018,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
dc_stream_retain(state->stream);
}
 
-   state->adjust = cur->adjust;
+   state->vrr_params = cur->vrr_params;
state->vrr_infopacket = cur->vrr_infopacket;
state->abm_level = cur->abm_level;
state->vrr_supported = cur->vrr_supported;
@@ -4396,9 +4413,11 @@ struct dc_stream_status *dc_state_get_stream_status(
 static void update_freesync_state_on_stream(
struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
-   struct dc_stream_state *new_stream)
+   struct dc_stream_state *new_stream,
+   struct dc_plane_state *surface,
+   u32 flip_timestamp_in_us)
 {
-   struct mod_vrr_params vrr = {0};
+   struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
struct dc_info_packet vrr_infopacket = {0};
struct mod_freesync_config config = new_crtc_state->freesync_config;
 
@@ -4425,43 +,52 @@ static void update_freesync_state_on_stream(
 
mod_freesync_build_vrr_params(dm->freesync_module,
  new_stream,
- , );
+ , _params);
+
+   if (surface) {
+   mod_freesync_handle_preflip(
+   dm->freesync_module,
+   surface,
+   new_stream,
+   flip_timestamp_in_us,
+   _params);
+   }
 
mod_freesync_build_vrr_infopacket(
dm->freesync_module,
new_stream,
-   ,
+   _params,
PACKET_TYPE_VRR,
TRANSFER_FUNC_UNKNOWN,
_infopacket);
 
new_crtc_state->freesync_timing_changed =
-   (memcmp(_crtc_state->adjust,
-   ,
-   sizeof(vrr.adjust)) != 0);
+   (memcmp(_crtc_state->vrr_params.adjust,
+   _params.adjust,
+   sizeof(vrr_params.adjust)) != 0);
 
new_crtc_state->freesync_vrr_info_changed =
(memcmp(_crtc_state->vrr_infopacket,
_infopacket,
sizeof(vrr_infopacket)) != 0);

Re: [PATCH] drm/amd/display: Add below the range support for FreeSync

2018-12-05 Thread Nicholas Kazlauskas
On 2018-12-05 9:30 a.m., Li, Sun peng (Leo) wrote:
> 
> 
> On 2018-12-05 8:40 a.m., Nicholas Kazlauskas wrote:
>> [Why]
>> When application flip-rate is below the minimum vrr refresh rate.
>>
>> Variable refresh rate monitors extend the front porch duration until
>> flip or timeout occurs. For cases where the application flip-rate is
> 
> Did something get cut off here? With that fixed,
> Acked-by: Leo Li 

Those top two paragraphs were supposed to be cut, I think I formatted 
the wrong patch for that.

The code itself is the correct version, however. Thanks.

Nicholas Kazlauskas

> 
>>
>> When the flip-rate is below the minimum supported variable refresh rate
>> range for the monitor the front porch wait will timeout and be
>> frequently misaligned resulting in stuttering and/or flickering.
>>
>> The FreeSync module can still maintain a smooth and flicker free
>> image when the monitor has a refresh rate range such that the maximum
>> refresh > 2 * minimum refresh by utilizing low framerate compensation,
>> "below the range".
>>
>> [How]
>> Hook up the pre-flip and post-flip handlers from the FreeSync module.
>> These adjust the minimum/maximum vrr range to duplicate frames
>> when appropriate by tracking flip timestamps.
>>
>> Cc: Leo Li 
>> Cc: Harry Wentland 
>> Signed-off-by: Nicholas Kazlauskas 
>> ---
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 79 ++-
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
>>2 files changed, 62 insertions(+), 19 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 23d61570df17..e2de064426fc 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -328,12 +328,29 @@ static void dm_crtc_high_irq(void *interrupt_params)
>>  struct common_irq_params *irq_params = interrupt_params;
>>  struct amdgpu_device *adev = irq_params->adev;
>>  struct amdgpu_crtc *acrtc;
>> +struct dm_crtc_state *acrtc_state;
>>
>>  acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - 
>> IRQ_TYPE_VBLANK);
>>
>>  if (acrtc) {
>>  drm_crtc_handle_vblank(>base);
>>  amdgpu_dm_crtc_handle_crc_irq(>base);
>> +
>> +acrtc_state = to_dm_crtc_state(acrtc->base.state);
>> +
>> +if (acrtc_state->stream &&
>> +acrtc_state->vrr_params.supported &&
>> +acrtc_state->freesync_config.state == 
>> VRR_STATE_ACTIVE_VARIABLE) {
>> +mod_freesync_handle_v_update(
>> +adev->dm.freesync_module,
>> +acrtc_state->stream,
>> +_state->vrr_params);
>> +
>> +dc_stream_adjust_vmin_vmax(
>> +adev->dm.dc,
>> +acrtc_state->stream,
>> +_state->vrr_params.adjust);
>> +}
>>  }
>>}
>>
>> @@ -3001,7 +3018,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
>>  dc_stream_retain(state->stream);
>>  }
>>
>> -state->adjust = cur->adjust;
>> +state->vrr_params = cur->vrr_params;
>>  state->vrr_infopacket = cur->vrr_infopacket;
>>  state->abm_level = cur->abm_level;
>>  state->vrr_supported = cur->vrr_supported;
>> @@ -4396,9 +4413,11 @@ struct dc_stream_status *dc_state_get_stream_status(
>>static void update_freesync_state_on_stream(
>>  struct amdgpu_display_manager *dm,
>>  struct dm_crtc_state *new_crtc_state,
>> -struct dc_stream_state *new_stream)
>> +struct dc_stream_state *new_stream,
>> +struct dc_plane_state *surface,
>> +u32 flip_timestamp_in_us)
>>{
>> -struct mod_vrr_params vrr = {0};
>> +struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
>>  struct dc_info_packet vrr_infopacket = {0};
>>  struct mod_freesync_config config = new_crtc_state->freesync_config;
>>
>> @@ -4425,43 +,52 @@ static void update_freesync_state_on_stream(
>>
>>  mod_freesync_build_vrr_params(dm->freesync_module,
>>new_stream,
>> -  

[PATCH] drm/amd/display: Add fast path for cursor plane updates

2018-12-05 Thread Nicholas Kazlauskas
[Why]
Legacy cursor plane updates from drm helpers go through the full
atomic codepath. A high volume of cursor updates through this slow
code path can cause subsequent page-flips to skip vblank intervals
since each individual update is slow.

This problem is particularly noticeable for the compton compositor.

[How]
A fast path for cursor plane updates is added by using DRM asynchronous
commit support provided by async_check and async_update. These don't do
a full state/flip_done dependency stall and they don't block other
commit work.

However, DC still expects itself to be single-threaded for anything
that can issue register writes. Screen corruption or hangs can occur
if write sequences overlap. Every call that potentially perform
register writes needs to be guarded for asynchronous updates to work.
The dc_lock mutex was added for this.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106175

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 67 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  8 +++
 2 files changed, 73 insertions(+), 2 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 23d61570df17..4df14a50a8ac 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -57,6 +57,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -133,6 +134,8 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state);
 static int amdgpu_dm_atomic_check(struct drm_device *dev,
  struct drm_atomic_state *state);
 
+static void handle_cursor_update(struct drm_plane *plane,
+struct drm_plane_state *old_plane_state);
 
 
 
@@ -402,6 +405,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
/* Zero all the fields */
memset(_data, 0, sizeof(init_data));
 
+   mutex_init(>dm.dc_lock);
+
if(amdgpu_dm_irq_init(adev)) {
DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n");
goto error;
@@ -516,6 +521,9 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
/* DC Destroy TODO: Replace destroy DAL */
if (adev->dm.dc)
dc_destroy(>dm.dc);
+
+   mutex_destroy(>dm.dc_lock);
+
return;
 }
 
@@ -3615,10 +3623,43 @@ static int dm_plane_atomic_check(struct drm_plane 
*plane,
return -EINVAL;
 }
 
+static int dm_plane_atomic_async_check(struct drm_plane *plane,
+  struct drm_plane_state *new_plane_state)
+{
+   /* Only support async updates on cursor planes. */
+   if (plane->type != DRM_PLANE_TYPE_CURSOR)
+   return -EINVAL;
+
+   return 0;
+}
+
+static void dm_plane_atomic_async_update(struct drm_plane *plane,
+struct drm_plane_state *new_state)
+{
+   struct drm_plane_state *old_state =
+   drm_atomic_get_old_plane_state(new_state->state, plane);
+
+   if (plane->state->fb != new_state->fb)
+   drm_atomic_set_fb_for_plane(plane->state, new_state->fb);
+
+   plane->state->src_x = new_state->src_x;
+   plane->state->src_y = new_state->src_y;
+   plane->state->src_w = new_state->src_w;
+   plane->state->src_h = new_state->src_h;
+   plane->state->crtc_x = new_state->crtc_x;
+   plane->state->crtc_y = new_state->crtc_y;
+   plane->state->crtc_w = new_state->crtc_w;
+   plane->state->crtc_h = new_state->crtc_h;
+
+   handle_cursor_update(plane, old_state);
+}
+
 static const struct drm_plane_helper_funcs dm_plane_helper_funcs = {
.prepare_fb = dm_plane_helper_prepare_fb,
.cleanup_fb = dm_plane_helper_cleanup_fb,
.atomic_check = dm_plane_atomic_check,
+   .atomic_async_check = dm_plane_atomic_async_check,
+   .atomic_async_update = dm_plane_atomic_async_update
 };
 
 /*
@@ -4307,6 +4348,7 @@ static int get_cursor_position(struct drm_plane *plane, 
struct drm_crtc *crtc,
 static void handle_cursor_update(struct drm_plane *plane,
 struct drm_plane_state *old_plane_state)
 {
+   struct amdgpu_device *adev = plane->dev->dev_private;
struct amdgpu_framebuffer *afb = 
to_amdgpu_framebuffer(plane->state->fb);
struct drm_crtc *crtc = afb ? plane->state->crtc : 
old_plane_state->crtc;
struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) 
: NULL;
@@ -4331,9 +4373,12 @@ static void handle_cursor_update(struct drm_plane *plane,
 
if (!position.enable) {
/* turn off cursor */
-   if (crtc_state && crtc_state->stream)
+   

Re: [PATCH] drm/amd/display: Add fast path for cursor plane updates

2018-12-05 Thread Nicholas Kazlauskas
On 2018-12-05 3:44 p.m., Grodzovsky, Andrey wrote:
> 
> 
> On 12/05/2018 03:42 PM, Kazlauskas, Nicholas wrote:
>> On 2018-12-05 3:26 p.m., Grodzovsky, Andrey wrote:
>>>
>>> On 12/05/2018 02:59 PM, Nicholas Kazlauskas wrote:
>>>> [Why]
>>>> Legacy cursor plane updates from drm helpers go through the full
>>>> atomic codepath. A high volume of cursor updates through this slow
>>>> code path can cause subsequent page-flips to skip vblank intervals
>>>> since each individual update is slow.
>>>>
>>>> This problem is particularly noticeable for the compton compositor.
>>>>
>>>> [How]
>>>> A fast path for cursor plane updates is added by using DRM asynchronous
>>>> commit support provided by async_check and async_update. These don't do
>>>> a full state/flip_done dependency stall and they don't block other
>>>> commit work.
>>>>
>>>> However, DC still expects itself to be single-threaded for anything
>>>> that can issue register writes. Screen corruption or hangs can occur
>>>> if write sequences overlap. Every call that potentially perform
>>>> register writes needs to be guarded for asynchronous updates to work.
>>>> The dc_lock mutex was added for this.
>>> As far as page flip related register writes concerned this I think this
>>> was never an issue - we always
>>> supported fully concurrent page flips on different CRTCs meaning writing
>>> surface address concurrently
>>> on different pipes. So Are you sure you  can't do cursor update
>>> concurrently against at least page flips ?
>>> I am not sure about full updates.
>>>
>>> Andrey
>> I think this was true before we started locking the pipes around cursor
>> updates (and probably only for dce). The problem that occur here is
>> writing to the lock register from multiple threads at the same time.
>>
>> In general I think the "contract" between dm/dc now is that anything
>> from dc that does register write sequences can't be called from multiple
>> threads.
>>
>> Nicholas Kazlauskas
> 
> Ok, do note that you also serialize all the page flips now which looks
> unneeded - maybe consider r/w lock to at least avoid that.
> 
> Andrey

Yeah, they definitely shouldn't be happening at the same time as the 
cursor calls.

I'd need to look into whether it's okay now to do concurrent writes from 
the stream update functions though, but I'd imagine it's not something 
we'd want to be doing. A r/w lock would work if we could though.

Nicholas Kazlauskas

> 
>>
>>>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106175
>>>>
>>>> Cc: Leo Li 
>>>> Cc: Harry Wentland 
>>>> Signed-off-by: Nicholas Kazlauskas 
>>>> ---
>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 67 ++-
>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  8 +++
>>>>  2 files changed, 73 insertions(+), 2 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 23d61570df17..4df14a50a8ac 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>> @@ -57,6 +57,7 @@
>>>>  
>>>>  #include 
>>>>  #include 
>>>> +#include 
>>>>  #include 
>>>>  #include 
>>>>  #include 
>>>> @@ -133,6 +134,8 @@ static void amdgpu_dm_atomic_commit_tail(struct 
>>>> drm_atomic_state *state);
>>>>  static int amdgpu_dm_atomic_check(struct drm_device *dev,
>>>>  struct drm_atomic_state *state);
>>>>  
>>>> +static void handle_cursor_update(struct drm_plane *plane,
>>>> +   struct drm_plane_state *old_plane_state);
>>>>  
>>>>  
>>>>  
>>>> @@ -402,6 +405,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>>>>/* Zero all the fields */
>>>>memset(_data, 0, sizeof(init_data));
>>>>  
>>>> +  mutex_init(>dm.dc_lock);
>>>> +
>>>>if(amdgpu_dm_irq_init(adev)) {
>>>>DRM_ERROR("amdgpu: failed to initialize DM 

Re: [PATCH] drm/amd/display: Add fast path for cursor plane updates

2018-12-05 Thread Nicholas Kazlauskas
On 2018-12-05 3:26 p.m., Grodzovsky, Andrey wrote:
> 
> 
> On 12/05/2018 02:59 PM, Nicholas Kazlauskas wrote:
>> [Why]
>> Legacy cursor plane updates from drm helpers go through the full
>> atomic codepath. A high volume of cursor updates through this slow
>> code path can cause subsequent page-flips to skip vblank intervals
>> since each individual update is slow.
>>
>> This problem is particularly noticeable for the compton compositor.
>>
>> [How]
>> A fast path for cursor plane updates is added by using DRM asynchronous
>> commit support provided by async_check and async_update. These don't do
>> a full state/flip_done dependency stall and they don't block other
>> commit work.
>>
>> However, DC still expects itself to be single-threaded for anything
>> that can issue register writes. Screen corruption or hangs can occur
>> if write sequences overlap. Every call that potentially perform
>> register writes needs to be guarded for asynchronous updates to work.
>> The dc_lock mutex was added for this.
> 
> As far as page flip related register writes concerned this I think this
> was never an issue - we always
> supported fully concurrent page flips on different CRTCs meaning writing
> surface address concurrently
> on different pipes. So Are you sure you  can't do cursor update
> concurrently against at least page flips ?
> I am not sure about full updates.
> 
> Andrey

I think this was true before we started locking the pipes around cursor 
updates (and probably only for dce). The problem that occur here is 
writing to the lock register from multiple threads at the same time.

In general I think the "contract" between dm/dc now is that anything 
from dc that does register write sequences can't be called from multiple 
threads.

Nicholas Kazlauskas

> 
>>
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106175
>>
>> Cc: Leo Li 
>> Cc: Harry Wentland 
>> Signed-off-by: Nicholas Kazlauskas 
>> ---
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 67 ++-
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  8 +++
>>2 files changed, 73 insertions(+), 2 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 23d61570df17..4df14a50a8ac 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -57,6 +57,7 @@
>>
>>#include 
>>#include 
>> +#include 
>>#include 
>>#include 
>>#include 
>> @@ -133,6 +134,8 @@ static void amdgpu_dm_atomic_commit_tail(struct 
>> drm_atomic_state *state);
>>static int amdgpu_dm_atomic_check(struct drm_device *dev,
>>struct drm_atomic_state *state);
>>
>> +static void handle_cursor_update(struct drm_plane *plane,
>> + struct drm_plane_state *old_plane_state);
>>
>>
>>
>> @@ -402,6 +405,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>>  /* Zero all the fields */
>>  memset(_data, 0, sizeof(init_data));
>>
>> +mutex_init(>dm.dc_lock);
>> +
>>  if(amdgpu_dm_irq_init(adev)) {
>>  DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n");
>>  goto error;
>> @@ -516,6 +521,9 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
>>  /* DC Destroy TODO: Replace destroy DAL */
>>  if (adev->dm.dc)
>>  dc_destroy(>dm.dc);
>> +
>> +mutex_destroy(>dm.dc_lock);
>> +
>>  return;
>>}
>>
>> @@ -3615,10 +3623,43 @@ static int dm_plane_atomic_check(struct drm_plane 
>> *plane,
>>  return -EINVAL;
>>}
>>
>> +static int dm_plane_atomic_async_check(struct drm_plane *plane,
>> +   struct drm_plane_state *new_plane_state)
>> +{
>> +/* Only support async updates on cursor planes. */
>> +if (plane->type != DRM_PLANE_TYPE_CURSOR)
>> +return -EINVAL;
>> +
>> +return 0;
>> +}
>> +
>> +static void dm_plane_atomic_async_update(struct drm_plane *plane,
>> + struct drm_plane_state *new_state)
>> +{
>> +struct drm_plane_state *old_state =
>> +drm_atomic_get_old_plane_state(new_state->state, plane);
>> +
>> +if (plane->state->fb != new_state->fb)
>&

[PATCH] Revert "drm/amd/display: Set RMX_ASPECT as default"

2018-12-07 Thread Nicholas Kazlauskas
This reverts commit 91b66c47ba3468f7882ea4a84d5e0e0c186b638f.

Forcing RMX_ASPECT as default uses the preferred/native mode's timings
for any mode the user selects and scales the image. This provides a
a consistently nicer result in the case where the selected mode's
refresh rate matches the native mode's refresh but this isn't always
the case.

For example, if the monitor is 1080p@144Hz and the preferred mode is
60Hz then even if the user selects 1080p@144Hz as their selected mode
they'll get 1080p@60Hz.

Cc: Bhawanpreet Lakha 
Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++
 1 file changed, 2 insertions(+), 4 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 23d61570df17..fa2b00ad1713 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3100,10 +3100,8 @@ int amdgpu_dm_connector_atomic_set_property(struct 
drm_connector *connector,
rmx_type = RMX_FULL;
break;
case DRM_MODE_SCALE_NONE:
-   rmx_type = RMX_OFF;
-   break;
default:
-   rmx_type = RMX_ASPECT;
+   rmx_type = RMX_OFF;
break;
}
 
@@ -3216,7 +3214,7 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector 
*connector)
state = kzalloc(sizeof(*state), GFP_KERNEL);
 
if (state) {
-   state->scaling = RMX_ASPECT;
+   state->scaling = RMX_OFF;
state->underscan_enable = false;
state->underscan_hborder = 0;
state->underscan_vborder = 0;
-- 
2.17.1

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


[PATCH] drm/amd/display: Fix duplicating scaling/underscan connector state

2018-12-07 Thread Nicholas Kazlauskas
[Why]
These properties aren't being carried over when the atomic state.
This tricks atomic check and commit tail into performing underscan
and scaling operations when they aren't needed.

With the patch that forced scaling/RMX_ASPECT on by default this
results in many unnecessary surface updates and hangs under certain
conditions.

[How]
Duplicate the properties.

Fixes: 91b66c47ba34 ("drm/amd/display: Set RMX_ASPECT as default")

Cc: Bhawanpreet Lakha 
Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 23d61570df17..ddf5efd1a5f4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3242,6 +3242,10 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
 
new_state->freesync_capable = state->freesync_capable;
new_state->abm_level = state->abm_level;
+   new_state->scaling = state->scaling;
+   new_state->underscan_enable = state->underscan_enable;
+   new_state->underscan_hborder = state->underscan_hborder;
+   new_state->underscan_vborder = state->underscan_vborder;
new_state->max_bpc = state->max_bpc;
 
return _state->base;
-- 
2.17.1

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


[PATCH] drm/amd/display: Fix unintialized max_bpc state values

2018-11-29 Thread Nicholas Kazlauskas
[Why]
If the "max bpc" isn't explicitly set in the atomic state then it
have a value of 0. This has the correct behavior of limiting a panel
to 8bpc in the case where the panel supports 8bpc. In the case of eDP
panels this isn't a true assumption - there are panels that can only
do 6bpc.

Banding occurs for these displays.

[How]
Initialize the max_bpc when the connector resets to 8bpc. Also carry
over the value when the state is duplicated.

Bugzilla: https://bugs.freedesktop.org/108825
Fixes: 307638884f72 ("drm/amd/display: Support amdgpu "max bpc" connector 
property")

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ce00e56814ed..ede93d53e209 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3215,6 +3215,7 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector 
*connector)
state->underscan_enable = false;
state->underscan_hborder = 0;
state->underscan_vborder = 0;
+   state->max_bpc = 8;
 
__drm_atomic_helper_connector_reset(connector, >base);
}
@@ -3236,6 +3237,7 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
 
new_state->freesync_capable = state->freesync_capable;
new_state->abm_level = state->abm_level;
+   new_state->max_bpc = state->max_bpc;
 
return _state->base;
 }
-- 
2.17.1

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


[PATCH] drm/amd/display: Fix NULL dereference when preferred_mode is NULL

2018-11-29 Thread Nicholas Kazlauskas
[Why]
When preferred_mode is NULL a null pointer dereference can occur
when trying to get the preferred refresh in create_stream_for_sink.

[How]
Only query preferred_refresh when preferred_mode is not NULL. Consider
preferred_refresh if it is since it's only being used to compare to
the previous value.

Fixes: b333730d126e ("drm/amd/display: Fix Scaling (RMX_*) for DC driver")

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 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 ce00e56814ed..478fa810438e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2848,7 +2848,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
bool native_mode_found = false;
bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
int mode_refresh;
-   int preferred_refresh;
+   int preferred_refresh = 0;
 
struct dc_sink *sink = NULL;
if (aconnector == NULL) {
@@ -2907,7 +2907,8 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
if (!dm_state)
drm_mode_set_crtcinfo(, 0);
 
-   preferred_refresh = drm_mode_vrefresh(preferred_mode);
+   if (preferred_mode)
+   preferred_refresh = drm_mode_vrefresh(preferred_mode);
 
/*
* If scaling is enabled and refresh rate didn't change
-- 
2.17.1

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


[PATCH v2] drm/amd/display: Add below the range support for FreeSync

2018-12-05 Thread Nicholas Kazlauskas
[Why]
When the flip-rate is below the minimum supported variable refresh rate
range for the monitor the front porch wait will timeout and be
frequently misaligned resulting in stuttering and/or flickering.

The FreeSync module can still maintain a smooth and flicker free
image when the monitor has a refresh rate range such that the maximum
refresh > 2 * minimum refresh by utilizing low framerate compensation,
"below the range".

[How]
Hook up the pre-flip and post-flip handlers from the FreeSync module.
These adjust the minimum/maximum vrr range to duplicate frames
when appropriate by tracking flip timestamps.

Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
Acked-by: Leo Li 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 79 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
 2 files changed, 62 insertions(+), 19 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 23d61570df17..e2de064426fc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -328,12 +328,29 @@ static void dm_crtc_high_irq(void *interrupt_params)
struct common_irq_params *irq_params = interrupt_params;
struct amdgpu_device *adev = irq_params->adev;
struct amdgpu_crtc *acrtc;
+   struct dm_crtc_state *acrtc_state;
 
acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - 
IRQ_TYPE_VBLANK);
 
if (acrtc) {
drm_crtc_handle_vblank(>base);
amdgpu_dm_crtc_handle_crc_irq(>base);
+
+   acrtc_state = to_dm_crtc_state(acrtc->base.state);
+
+   if (acrtc_state->stream &&
+   acrtc_state->vrr_params.supported &&
+   acrtc_state->freesync_config.state == 
VRR_STATE_ACTIVE_VARIABLE) {
+   mod_freesync_handle_v_update(
+   adev->dm.freesync_module,
+   acrtc_state->stream,
+   _state->vrr_params);
+
+   dc_stream_adjust_vmin_vmax(
+   adev->dm.dc,
+   acrtc_state->stream,
+   _state->vrr_params.adjust);
+   }
}
 }
 
@@ -3001,7 +3018,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
dc_stream_retain(state->stream);
}
 
-   state->adjust = cur->adjust;
+   state->vrr_params = cur->vrr_params;
state->vrr_infopacket = cur->vrr_infopacket;
state->abm_level = cur->abm_level;
state->vrr_supported = cur->vrr_supported;
@@ -4396,9 +4413,11 @@ struct dc_stream_status *dc_state_get_stream_status(
 static void update_freesync_state_on_stream(
struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
-   struct dc_stream_state *new_stream)
+   struct dc_stream_state *new_stream,
+   struct dc_plane_state *surface,
+   u32 flip_timestamp_in_us)
 {
-   struct mod_vrr_params vrr = {0};
+   struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
struct dc_info_packet vrr_infopacket = {0};
struct mod_freesync_config config = new_crtc_state->freesync_config;
 
@@ -4425,43 +,52 @@ static void update_freesync_state_on_stream(
 
mod_freesync_build_vrr_params(dm->freesync_module,
  new_stream,
- , );
+ , _params);
+
+   if (surface) {
+   mod_freesync_handle_preflip(
+   dm->freesync_module,
+   surface,
+   new_stream,
+   flip_timestamp_in_us,
+   _params);
+   }
 
mod_freesync_build_vrr_infopacket(
dm->freesync_module,
new_stream,
-   ,
+   _params,
PACKET_TYPE_VRR,
TRANSFER_FUNC_UNKNOWN,
_infopacket);
 
new_crtc_state->freesync_timing_changed =
-   (memcmp(_crtc_state->adjust,
-   ,
-   sizeof(vrr.adjust)) != 0);
+   (memcmp(_crtc_state->vrr_params.adjust,
+   _params.adjust,
+   sizeof(vrr_params.adjust)) != 0);
 
new_crtc_state->freesync_vrr_info_changed =
(memcmp(_crtc_state->vrr_infopacket,
_infopacket,
sizeof(vrr_infopacket)) != 0);
 
-   new_crtc_state->adjust = vrr.adjust;
+   new_crtc_state->vrr_params = vrr_params;
new_crtc_state->vrr_infopacket = vrr_infopacket;
 
-   new_stream->ad

[PATCH 2/2] drm/amd/display: Remove wait for hw/flip done in atomic check

2018-11-22 Thread Nicholas Kazlauskas
[Why]
Atomic check can't truly be non-blocking if amdgpu_dm is waiting for
hw_done and flip_done in atomic check. This introduces waits when
any previous non-blocking commits queued work on a worker thread and
a new atomic commit attempts to do another full update/modeset.

[How]
Drop the waits and move the global lock acqusition into atomic check.

This is fine to do since commit tail waits for these dependencies
before calling amdgpu_dm_atomic_commit_tail.

This is only safe as long as DC never queries anything from within
current_state when doing validation in atomic_check. This is the
case as of writing, but any future uses of dc->current_state from
within atomic_check should be considered incorrect.

Cc: Harry Wentland 
Cc: Leo Li 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 58 ++-
 1 file changed, 6 insertions(+), 52 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 3ae438d9849f..fe21bb86b66a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5078,57 +5078,6 @@ void dm_restore_drm_connector_state(struct drm_device 
*dev,
dm_force_atomic_commit(>base);
 }
 
-/*
- * Grabs all modesetting locks to serialize against any blocking commits,
- * Waits for completion of all non blocking commits.
- */
-static int do_aquire_global_lock(struct drm_device *dev,
-struct drm_atomic_state *state)
-{
-   struct drm_crtc *crtc;
-   struct drm_crtc_commit *commit;
-   long ret;
-
-   /*
-* Adding all modeset locks to aquire_ctx will
-* ensure that when the framework release it the
-* extra locks we are locking here will get released to
-*/
-   ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
-   if (ret)
-   return ret;
-
-   list_for_each_entry(crtc, >mode_config.crtc_list, head) {
-   spin_lock(>commit_lock);
-   commit = list_first_entry_or_null(>commit_list,
-   struct drm_crtc_commit, commit_entry);
-   if (commit)
-   drm_crtc_commit_get(commit);
-   spin_unlock(>commit_lock);
-
-   if (!commit)
-   continue;
-
-   /*
-* Make sure all pending HW programming completed and
-* page flips done
-*/
-   ret = 
wait_for_completion_interruptible_timeout(>hw_done, 10*HZ);
-
-   if (ret > 0)
-   ret = wait_for_completion_interruptible_timeout(
-   >flip_done, 10*HZ);
-
-   if (ret == 0)
-   DRM_ERROR("[CRTC:%d:%s] hw_done or flip_done "
- "timed out\n", crtc->base.id, crtc->name);
-
-   drm_crtc_commit_put(commit);
-   }
-
-   return ret < 0 ? ret : 0;
-}
-
 void set_freesync_on_stream(struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
struct dm_connector_state *new_con_state,
@@ -5793,7 +5742,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
 
-   ret = do_aquire_global_lock(dev, state);
+   /*
+* This should be replaced with finer locking on the
+* on the appropriate resources when possible.
+* For now it's safer to grab everything.
+*/
+   ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
if (ret)
goto fail;
 
-- 
2.17.1

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


[PATCH 1/2] drm/amd/display: Use private obj helpers for dm_atomic_state

2018-11-22 Thread Nicholas Kazlauskas
[Why]
Two non-blocking commits in succession can result in a sequence where
the same dc->current_state is queried for both commits.

1. 1st commit -> check -> commit -> swaps atomic state -> queues work
2. 2nd commit -> check -> commit -> swaps atomic state -> queues work
3. 1st commit work finishes

The issue with this sequence is that the same dc->current_state is
read in both atomic checks. If the first commit modifies streams or
planes those will be missing from the dc->current_state for the
second atomic check. This result in many stream and plane errors in
atomic commit tail.

[How]
The driver still needs to track old to new state to determine if the
commit in its current implementation. Updating the dc_state in
atomic tail is wrong since the dc_state swap should be happening as
part of drm_atomic_helper_swap_state *before* the worker queue kicks
its work off.

The simplest replacement for the subclassing (which doesn't properly
manage the old to new atomic state swap) is to use the drm private
object helpers. While some of the dc_state members could be merged
into dm_crtc_state or dm_plane_state and copied over that way it is
easier for now to just treat the whole dc_state structure as a single
private object.

This allows amdgpu_dm to drop the dc->current_state copy from within
atomic check. It's replaced by a copy from the current atomic state
which is propagated correctly for the sequence described above.

Since access to the dm_state private object is now locked this should
also fix issues that could arise if submitting non-blocking commits
from different threads.

Cc: Harry Wentland 
Cc: Leo Li 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 290 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  13 +-
 2 files changed, 234 insertions(+), 69 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 8433d31cdea8..3ae438d9849f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -968,45 +968,6 @@ const struct amdgpu_ip_block_version dm_ip_block =
 };
 
 
-static struct drm_atomic_state *
-dm_atomic_state_alloc(struct drm_device *dev)
-{
-   struct dm_atomic_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
-
-   if (!state)
-   return NULL;
-
-   if (drm_atomic_state_init(dev, >base) < 0)
-   goto fail;
-
-   return >base;
-
-fail:
-   kfree(state);
-   return NULL;
-}
-
-static void
-dm_atomic_state_clear(struct drm_atomic_state *state)
-{
-   struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
-
-   if (dm_state->context) {
-   dc_release_state(dm_state->context);
-   dm_state->context = NULL;
-   }
-
-   drm_atomic_state_default_clear(state);
-}
-
-static void
-dm_atomic_state_alloc_free(struct drm_atomic_state *state)
-{
-   struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
-   drm_atomic_state_default_release(state);
-   kfree(dm_state);
-}
-
 /**
  * DOC: atomic
  *
@@ -1018,9 +979,6 @@ static const struct drm_mode_config_funcs 
amdgpu_dm_mode_funcs = {
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = amdgpu_dm_atomic_check,
.atomic_commit = amdgpu_dm_atomic_commit,
-   .atomic_state_alloc = dm_atomic_state_alloc,
-   .atomic_state_clear = dm_atomic_state_clear,
-   .atomic_state_free = dm_atomic_state_alloc_free
 };
 
 static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = 
{
@@ -1542,8 +1500,117 @@ static int dcn10_register_irq_handlers(struct 
amdgpu_device *adev)
 }
 #endif
 
+/*
+ * Acquires the lock for the atomic state object and returns
+ * the new atomic state.
+ *
+ * This should only be called during atomic check.
+ */
+static int dm_atomic_get_state(struct drm_atomic_state *state,
+  struct dm_atomic_state **dm_state)
+{
+   struct drm_device *dev = state->dev;
+   struct amdgpu_device *adev = dev->dev_private;
+   struct amdgpu_display_manager *dm = >dm;
+   struct drm_private_state *priv_state;
+   int ret;
+
+   if (*dm_state)
+   return 0;
+
+   ret = drm_modeset_lock(>atomic_obj_lock, state->acquire_ctx);
+   if (ret)
+   return ret;
+
+   priv_state = drm_atomic_get_private_obj_state(state, >atomic_obj);
+   if (IS_ERR(priv_state))
+   return PTR_ERR(priv_state);
+
+   *dm_state = to_dm_atomic_state(priv_state);
+
+   return 0;
+}
+
+struct dm_atomic_state *
+dm_atomic_get_new_state(struct drm_atomic_state *state)
+{
+   struct drm_device *dev = state->dev;
+   struct amdgpu_device *adev = dev->dev_private;
+   struct amdgpu_display_manager *dm = >dm;
+  

[PATCH] drm/amd/display: Only get the connector state for VRR when toggled

2019-01-10 Thread Nicholas Kazlauskas
[Why]
This fixes a stuttering issue that occurs when moving a hardware cursor
when VRR is enabled.

Previously when VRR is enabled atomic check will grab the connector
state for every atomic update. This has to lock the connector in order
to do so. The locking is bad enough by itself for performance, but
it gets worse with what we do just below that - add all the planes
for the CRTC to the commit.

This prevents the cursor fast path from working - there's more than one
plane now. With state->allow_modeset = true on top of this, it also
adds and removes all the planes from the DC context triggering a full
(very slow) update in DC.

[How]
We need the connector state to get the VRR min/max capbilities, but we
only need them when there's a CRTC mode change or when VRR is toggled.

The condition has been updated accordingly.

Fixes: 3cc22f281318 ("drm/amdgpu: Set FreeSync state using drm VRR properties")

Cc: Harry Wentland 
Cc: Leo Li 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 4839d2dc..b7867ec166f3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6083,7 +6083,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
!new_crtc_state->color_mgmt_changed &&
-   !new_crtc_state->vrr_enabled)
+   old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled)
continue;
 
if (!new_crtc_state->enable)
-- 
2.17.1

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


[PATCH 1/9] drm: Add variable refresh rate properties to DRM connector

2018-09-11 Thread Nicholas Kazlauskas
Modern monitor hardware is capable of supporting variable refresh rates
and adaptive sync technologies. The properties for querying and
controlling these features should be exposed on the DRM connector.

This patch introduces two new properties for variable refresh rate
support:

- variable_refresh_capable
- variable_refresh_enabled

These are optional properties that can be added to a DRM connector
dynamically by using drm_connector_attach_variable_refresh_properties.

DRM drivers should set variable_refresh_capable as applicable for
their hardware. The property variable_refresh_enabled as a userspace
controlled option.

Change-Id: I5f60f8b57534e1d3dacda4c64c6c9106b42f4439
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic.c|  9 +
 drivers/gpu/drm/drm_connector.c | 35 +
 include/drm/drm_connector.h | 27 +
 3 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index d0478abc01bd..2f89ab0fac87 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1403,6 +1403,11 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->content_type = val;
} else if (property == connector->scaling_mode_property) {
state->scaling_mode = val;
+   } else if (property == connector->variable_refresh_capable_property) {
+   DRM_DEBUG_KMS("only drivers can set 
variable_refresh_capable\n");
+   return -EINVAL;
+   } else if (property == connector->variable_refresh_enabled_property) {
+   state->variable_refresh_enabled = val;
} else if (property == connector->content_protection_property) {
if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
@@ -1508,6 +1513,10 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->content_type;
} else if (property == connector->scaling_mode_property) {
*val = state->scaling_mode;
+   } else if (property == connector->variable_refresh_capable_property) {
+   *val = state->variable_refresh_capable;
+   } else if (property == connector->variable_refresh_enabled_property) {
+   *val = state->variable_refresh_enabled;
} else if (property == connector->content_protection_property) {
*val = state->content_protection;
} else if (property == config->writeback_fb_id_property) {
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 6011d769d50b..37fb33fa77b9 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1250,6 +1250,41 @@ int drm_mode_create_scaling_mode_property(struct 
drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 
+/**
+ * drm_connector_attach_variable_refresh_properties - creates and attaches
+ * properties for connectors that support adaptive refresh
+ * @connector: connector to create adaptive refresh properties on
+ */
+int drm_connector_attach_variable_refresh_properties(
+   struct drm_connector *connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->variable_refresh_capable_property) {
+   prop = drm_property_create_bool(dev, 0,
+   "variable_refresh_capable");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->variable_refresh_capable_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   if (!connector->variable_refresh_enabled_property) {
+   prop = drm_property_create_bool(dev, 0,
+   "variable_refresh_enabled");
+   if (!prop)
+   return -ENOMEM;
+
+   connector->variable_refresh_enabled_property = prop;
+   drm_object_attach_property(>base, prop, 0);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_variable_refresh_properties);
+
 /**
  * drm_connector_attach_scaling_mode_property - attach atomic scaling mode 
property
  * @connector: connector to attach scaling mode property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 97ea41dc678f..105a127e9191 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -448,6 +448,18 @@ struct drm_connector_state {
 */
unsigned int content_protection;
 
+   /**
+* @variable_refresh_enabled: Connector property used to check
+* if variable refresh is supported on the device.
+*/
+   bool variable_refresh_capable;
+
+   /**

[PATCH 0/9] A DRM API for adaptive sync and variable refresh rate support

2018-09-11 Thread Nicholas Kazlauskas
=== Adaptive sync and variable refresh rate ===

Adaptive sync is part of the DisplayPort spec and allows for graphics adapters 
to drive displays with varying frame timings.

Variable refresh rate (VRR) is essentially the same, but defined for HDMI.

=== Use cases for variable refresh rate ===

Variable frame (flip) timings don't align well with fixed refresh rate 
displays. This results in stuttering, tearing and/or input lag. By adjusting 
the display refresh rate dynamically these issues can be reduced or eliminated.

However, not all content is suitable for dynamic refresh adaptation. Content 
that is flipped infrequently or at random intervals tends to fair poorly. 
Multiple clients trying to flip under the same screen can similarly interfere 
with prediction.

Userland needs a way to let the driver know when the content on the screen is 
suitable for variable refresh rate and if the user wishes to have the feature 
enabled.

=== DRM API to support variable refresh rates ===

This patch introduces a new API via atomic properties on the DRM connector and 
CRTC.

The connector has two new optional properties:

* bool variable_refresh_capable - set by the driver if the hardware is capable 
of supporting variable refresh tech

* bool variable_refresh_enabled - set by the user to enable variable refresh 
adjustment over the connector

The CRTC has one additional default property:

* bool variable_refresh - a content hint to the driver specifying that the CRTC 
contents are suitable for variable refresh adjustment

== Overview for DRM driver developers ===

Driver developers can attach the optional connector properties via 
drm_connector_attach_variable_refresh_properties on connectors that support 
variable refresh (typically DP or HDMI).

The variable_refresh_capable property should be managed as the output on the 
connector changes. The property is read only from userspace.

The variable_refresh_enabled property is intended to be a property controlled 
by userland as a global on/off switch for variable refresh technology. It 
should be checked before enabling variable refresh rate.

=== Overview for Userland developers ==

The variable_refresh property on the CRTC should be set to true when the CRTCs 
are suitable for variable refresh rate. In practice this is probably an 
application like a game - a single window that covers the whole CRTC surface 
and is the only client issuing flips.

To demonstrate the suitability of the API for variable refresh and dynamic 
adaptation there are additional patches using this API that implement adaptive 
variable refresh across kernel and userland projects:

- DRM (dri-devel)
- amdgpu DRM kernel driver (amd-gfx)
- xf86-video-amdgpu (amd-gfx)
- mesa (mesa-dev)

These patches enable adaptive variable refresh on X for AMD hardware provided 
that the user sets the variable_refresh_enabled property to true on supported 
connectors (ie. using xrandr --set-prop).

They have been tested on upstream userland under GNOME/KDE desktop environments 
under single and multi-monitor setups for a number of GL applications. Most 
games and benchmarks should work as expected provided that the compositor 
correctly unredirects the application's surface. KDE seems to have the best 
support for this with an explicit option to disable tearing support.

Full implementation details for these changes can be reviewed in their 
respective mailing lists.

=== Previous discussions ===

These patches are based upon feedback from patches and feedback from two 
previous threads on the subject which are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html

Nicholas Kazlauskas

Anthony Koo (1):
  drm/amd/display: Refactor FreeSync module

Harry Wentland (3):
  drm/amdgpu: fill in amdgpu_dm_remove_sink_from_freesync_module
  drm/amdgpu/display: add freesync drm properties
  drm/amdgpu: add freesync ioctl

Nicholas Kazlauskas (5):
  drm: Add variable refresh rate properties to DRM connector
  drm: Add variable refresh property to DRM CRTC
  drm/amd/display: Replace FreeSync props with DRM VRR props
  drm/amd/display: Drop FreeSync ioctl notification support
  drm/amdgpu: Drop unneeded freesync properties from amdpgu

 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |3 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |   16 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c   |3 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  240 +--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   17 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   10 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |   60 +-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |3 +
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  110 +-
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |6 -
 drivers/gpu/drm/amd/display/dc/dc_stream.h|   29 +-
 drivers/gpu/drm/amd/display/dc/dc_types.h |   22

[PATCH 2/9] drm: Add variable refresh property to DRM CRTC

2018-09-11 Thread Nicholas Kazlauskas
Variable refresh rate algorithms have typically been enabled only
when the display is covered by a single source of content.

This patch introduces a new default CRTC property that helps
hint to the driver when the CRTC composition is suitable for variable
refresh rate algorithms. Userspace can set this property dynamically
as the composition changes.

Whether the variable refresh rate algorithms are active will still
depend on the CRTC being suitable and the connector being capable
and enabled by the user for variable refresh rate support.

It is worth noting that while the property is atomic it isn't filtered
from legacy userspace queries. This allows for Xorg userspace drivers
to implement support in non-atomic setups.

Change-Id: I5a5044f48fc68fcdbcfaa5141e83b44747d7116b
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/drm_atomic.c|  6 ++
 drivers/gpu/drm/drm_atomic_helper.c |  1 +
 drivers/gpu/drm/drm_crtc.c  |  2 ++
 drivers/gpu/drm/drm_mode_config.c   |  6 ++
 include/drm/drm_crtc.h  | 13 +
 include/drm/drm_mode_config.h   |  8 
 6 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 2f89ab0fac87..46c50c1f267b 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -553,6 +553,10 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
drm_property_blob_put(mode);
return ret;
+   } else if (property == config->prop_variable_refresh) {
+   if (state->variable_refresh != val)
+   state->variable_refresh_changed = true;
+   state->variable_refresh = val;
} else if (property == config->degamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
@@ -627,6 +631,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->active;
else if (property == config->prop_mode_id)
*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+   else if (property == config->prop_variable_refresh)
+   *val = state->variable_refresh;
else if (property == config->degamma_lut_property)
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 2c23a48482da..dd01ab041eff 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3472,6 +3472,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct 
drm_crtc *crtc,
state->planes_changed = false;
state->connectors_changed = false;
state->color_mgmt_changed = false;
+   state->variable_refresh_changed = false;
state->zpos_changed = false;
state->commit = NULL;
state->event = NULL;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index bae43938c8f6..f18b60ce7599 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -337,6 +337,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
drm_object_attach_property(>base, config->prop_mode_id, 
0);
drm_object_attach_property(>base,
   config->prop_out_fence_ptr, 0);
+   drm_object_attach_property(>base,
+  config->prop_variable_refresh, 0);
}
 
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index 21e353bd3948..5847ac1e88c1 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -311,6 +311,12 @@ static int drm_mode_create_standard_properties(struct 
drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
 
+   prop = drm_property_create_bool(dev, 0,
+   "VARIABLE_REFRESH");
+   if (!prop)
+   return -ENOMEM;
+   dev->mode_config.prop_variable_refresh = prop;
+
prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b21437bc95bf..32b77f18ce6d 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -168,6 +168,12 @@ struct drm_crtc_state {
 * drivers to steer the atomic commit control flow.
 */
bool color_mgmt_changed : 1;
+   /**
+* @variable_refresh_changed: Variable refresh support has changed
+* on the CRTC. Used by the atomic helper

[PATCH xf86-video-amdgpu 1/6] Enable/Disable freesync when enter/exit fullscreen game v2

2018-09-11 Thread Nicholas Kazlauskas
From: Hawking Zhang 

v2:
resolve undefined symbol in xserver 1.16

Signed-off-by: Hawking Zhang 
Signed-off-by: Nicholas Kazlauskas 
---
 src/Makefile.am|   2 +
 src/amdgpu_dri2.c  |  24 ++
 src/amdgpu_drv.h   |   5 ++
 src/amdgpu_extension.c | 176 +
 src/amdgpu_extension.h |  52 
 src/amdgpu_kms.c   |   4 +
 src/amdgpu_present.c   |  14 
 7 files changed, 277 insertions(+)
 create mode 100644 src/amdgpu_extension.c
 create mode 100644 src/amdgpu_extension.h

diff --git a/src/Makefile.am b/src/Makefile.am
index c23c87d..240cb89 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,7 @@ amdgpu_drv_ladir = @moduledir@/drivers
 amdgpu_drv_la_SOURCES = \
amdgpu_video.c \
amdgpu_misc.c amdgpu_probe.c \
+   amdgpu_extension.c \
$(AMDGPU_KMS_SRCS)
 
 AM_CFLAGS += @LIBGLAMOR_CFLAGS@
@@ -64,6 +65,7 @@ EXTRA_DIST = \
amdgpu_drv.h \
amdgpu_pixmap.h \
amdgpu_probe.h \
+   amdgpu_extension.h \
amdgpu_version.h \
amdgpu_video.h \
simple_list.h \
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 96b2d17..8c601c8 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -34,6 +34,7 @@
 #include "amdgpu_glamor.h"
 #include "amdgpu_video.h"
 #include "amdgpu_pixmap.h"
+#include "amdgpu_extension.h"
 
 #ifdef DRI2
 
@@ -527,6 +528,13 @@ amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr 
client,
xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
   "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info);
 
+   if (info->freesync_capable_client &&
+   info->freesync_enabled == FALSE) {
+   AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
+   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE))
+   info->freesync_enabled = TRUE;
+   }
+
/* Page flip the full screen buffer */
back_priv = back->driverPrivate;
if (amdgpu_do_pageflip(scrn, client, back_priv->pixmap,
@@ -680,6 +688,8 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr 
crtc, uint32_t seq,
 {
DRI2FrameEventPtr event = event_data;
ScrnInfoPtr scrn = crtc->scrn;
+   AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+   AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
DrawablePtr drawable;
int status;
int swap_type;
@@ -710,6 +720,12 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr 
crtc, uint32_t seq,
}
/* else fall through to exchange/blit */
case DRI2_SWAP:
+   if (info->freesync_capable_client &&
+   info->freesync_enabled == TRUE) {
+   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
+   info->freesync_enabled = FALSE;
+   }
+
if (DRI2CanExchange(drawable) &&
can_exchange(scrn, drawable, event->front, event->back)) {
amdgpu_dri2_exchange_buffers(drawable, event->front,
@@ -1076,6 +1092,8 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, 
DrawablePtr draw,
 {
ScreenPtr screen = draw->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+   AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
+   AMDGPUInfoPtr info = AMDGPUPTR(scrn);
xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
uint32_t msc_delta;
drmVBlankSeqType type;
@@ -1248,6 +1266,12 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, 
DrawablePtr draw,
return TRUE;
 
 blit_fallback:
+   if (info->freesync_capable_client &&
+   info->freesync_enabled == TRUE) {
+   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
+   info->freesync_enabled = FALSE;
+   }
+
if (swap_info) {
swap_info->type = DRI2_SWAP;
amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 45bc394..91bb829 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -303,6 +303,11 @@ typedef struct {
/* kms pageflipping */
Bool allowPageFlip;
 
+   /* freesync */
+   ClientPtr freesync_capable_client;
+   uint32_t client_resource_id;
+   Bool freesync_enabled;
+
/* cursor size */
int cursor_w;
int cursor_h;
diff --git a/src/amdgpu_extension.c b/src/amdgpu_extension.c
new file mode 100644
index 000..1c984df
--- /dev/null
+++ b/src/amdgpu_extension.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the 

[PATCH xf86-video-amdgpu 0/6] xf86-video-amdgpu integration for DRM variable refresh rate API

2018-09-11 Thread Nicholas Kazlauskas
These patches are part of a proposed new interface for supporting variable 
refresh rate via DRM properties.

https://patchwork.freedesktop.org/series/49486/

When notified of a window that is FreeSync capable via X these patches help 
track when the window is fullscreen to manage the variable_refresh property on 
the CRTC.

=== Adaptive sync and variable refresh rate ===

Adaptive sync is part of the DisplayPort spec and allows for graphics adapters 
to drive displays with varying frame timings.

Variable refresh rate (VRR) is essentially the same, but defined for HDMI.

=== Use cases for variable refresh rate ===

Variable frame (flip) timings don't align well with fixed refresh rate 
displays. This results in stuttering, tearing and/or input lag. By adjusting 
the display refresh rate dynamically these issues can be reduced or eliminated.

However, not all content is suitable for dynamic refresh adaptation. Content 
that is flipped infrequently or at random intervals tends to fair poorly. 
Multiple clients trying to flip under the same screen can similarly interfere 
with prediction.

Userland needs a way to let the driver know when the content on the screen is 
suitable for variable refresh rate and if the user wishes to have the feature 
enabled.

=== DRM API to support variable refresh rates ===

This patch introduces a new API via atomic properties on the DRM connector and 
CRTC.

The connector has two new optional properties:

* bool variable_refresh_capable - set by the driver if the hardware is capable 
of supporting variable refresh tech

* bool variable_refresh_enabled - set by the user to enable variable refresh 
adjustment over the connector

The CRTC has one additional default property:

* bool variable_refresh - a content hint to the driver specifying that the CRTC 
contents are suitable for variable refresh adjustment

== Overview for DRM driver developers ===

Driver developers can attach the optional connector properties via 
drm_connector_attach_variable_refresh_properties on connectors that support 
variable refresh (typically DP or HDMI).

The variable_refresh_capable property should be managed as the output on the 
connector changes. The property is read only from userspace.

The variable_refresh_enabled property is intended to be a property controlled 
by userland as a global on/off switch for variable refresh technology. It 
should be checked before enabling variable refresh rate.

=== Overview for Userland developers ==

The variable_refresh property on the CRTC should be set to true when the CRTCs 
are suitable for variable refresh rate. In practice this is probably an 
application like a game - a single window that covers the whole CRTC surface 
and is the only client issuing flips.

To demonstrate the suitability of the API for variable refresh and dynamic 
adaptation there are additional patches using this API that implement adaptive 
variable refresh across kernel and userland projects:

- DRM (dri-devel)
- amdgpu DRM kernel driver (amd-gfx)
- xf86-video-amdgpu (amd-gfx)
- mesa (mesa-dev)

These patches enable adaptive variable refresh on X for AMD hardware provided 
that the user sets the variable_refresh_enabled property to true on supported 
connectors (ie. using xrandr --set-prop).

They have been tested on upstream userland under GNOME/KDE desktop environments 
under single and multi-monitor setups for a number of GL applications. Most 
games and benchmarks should work as expected provided that the compositor 
correctly unredirects the application's surface. KDE seems to have the best 
support for this with an explicit option to disable tearing support.

Full implementation details for these changes can be reviewed in their 
respective mailing lists.

=== Previous discussions ===

These patches are based upon feedback from patches and feedback from two 
previous threads on the subject which are linked below for reference:

https://lists.freedesktop.org/archives/amd-gfx/2018-April/021047.html
https://lists.freedesktop.org/archives/dri-devel/2017-October/155207.html

Nicholas Kazlauskas

Hawking Zhang (5):
  Enable/Disable freesync when enter/exit fullscreen game v2
  Set freesync capability when client has fullscreen size drawable
  Do not fail the X request when there is just BadDrawable/BadMatch
  Handle Alt+Tab case when freesync enabled in steam client v2
  Do not issue freesync ioctl from present unflip

Nicholas Kazlauskas (1):
  Replace amdgpu ioctl with CRTC properties for enabling FreeSync

 src/Makefile.am|   2 +
 src/amdgpu_dri2.c  |   1 +
 src/amdgpu_drv.h   |  10 ++
 src/amdgpu_extension.c | 210 +
 src/amdgpu_extension.h |  53 +++
 src/amdgpu_kms.c   |  60 
 src/amdgpu_present.c   |   1 +
 src/drmmode_display.c  |  88 +
 src/drmmode_display.h  |   1 +
 9 files changed, 426 insertions(+)
 create mode 100644 src/amdgpu_extension.c
 create mode 100644 src

[PATCH 6/9] drm/amdgpu: add freesync ioctl

2018-09-11 Thread Nicholas Kazlauskas
From: Harry Wentland 

Add the ioctl to enable/disable freesync.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  3 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c  | 15 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c  |  3 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c|  4 
 include/uapi/drm/amdgpu_drm.h| 16 
 5 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 447c4c7a36d6..95af917007f7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1193,6 +1193,9 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, 
void *data,
 int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);
 
+int amdgpu_display_freesync_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp);
+
 /* VRAM scratch page for HDP bug, default vram page */
 struct amdgpu_vram_scratch {
struct amdgpu_bo*robj;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 642b47c5f4b8..7d6a36bca9dd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -894,3 +894,18 @@ int amdgpu_display_crtc_idx_to_irq_type(struct 
amdgpu_device *adev, int crtc)
return AMDGPU_CRTC_IRQ_NONE;
}
 }
+
+int amdgpu_display_freesync_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp)
+{
+   int ret = -EPERM;
+   struct amdgpu_device *adev = dev->dev_private;
+
+   if (adev->mode_info.funcs->notify_freesync)
+   ret = adev->mode_info.funcs->notify_freesync(dev,data,filp);
+   else
+   DRM_DEBUG("amdgpu no notify_freesync ioctl\n");
+
+   return ret;
+}
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index bd98cc5fb97b..5b26e0447221 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -1099,7 +1099,8 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
-   DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW)
+   DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(AMDGPU_FREESYNC, amdgpu_display_freesync_ioctl, 
DRM_MASTER)
 };
 const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms);
 
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 8be3028850b6..56598ed53123 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1584,6 +1584,7 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
 static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
struct drm_file *filp)
 {
+   struct drm_amdgpu_freesync *args = data;
struct drm_atomic_state *state;
struct drm_modeset_acquire_ctx ctx;
struct drm_crtc *crtc;
@@ -1593,6 +1594,9 @@ static int amdgpu_notify_freesync(struct drm_device *dev, 
void *data,
uint8_t i;
bool enable = false;
 
+   if (args->op == AMDGPU_FREESYNC_FULLSCREEN_ENTER)
+   enable = true;
+
drm_modeset_acquire_init(, 0);
 
state = drm_atomic_state_alloc(dev);
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 1ceec56de015..9eeba55b 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -54,6 +54,8 @@ extern "C" {
 #define DRM_AMDGPU_VM  0x13
 #define DRM_AMDGPU_FENCE_TO_HANDLE 0x14
 #define DRM_AMDGPU_SCHED   0x15
+/* not upstream */
+#define DRM_AMDGPU_FREESYNC0x5d
 
 #define DRM_IOCTL_AMDGPU_GEM_CREATEDRM_IOWR(DRM_COMMAND_BASE + 
DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
 #define DRM_IOCTL_AMDGPU_GEM_MMAP  DRM_IOWR(DRM_COMMAND_BASE + 
DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@@ -71,6 +73,7 @@ extern "C" {
 #define DRM_IOCTL_AMDGPU_VMDRM_IOWR(DRM_COMMAND_BASE + 
DRM_AMDGPU_VM, union drm_amdgpu_vm)
 #define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + 
DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
 #define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + 
DRM_AMDGPU_SCHED, union drm_amdgpu_sched)

[PATCH 7/9] drm/amd/display: Replace FreeSync props with DRM VRR props

2018-09-11 Thread Nicholas Kazlauskas
DRM has built-in support for variable refresh properties on the
connector and CRTC. Make use of these instead of the amdpgu specific
freesync properties.

The connector properties freesync and freesync_capable are replaced with
variable_refresh_enabled and variable_refresh_capable.

The CRTC property freesync_enable is replaced with the variable_refresh
property.

The old FreeSync properties are no longer accessible from userspace and
the DRM properties should be instead for enabling/disabling variable
refresh support.

Change-Id: I7c8117c09282a938c87292402af39d22e4eb823b
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 --
 2 files changed, 18 insertions(+), 35 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 56598ed53123..d28bab0f4657 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1632,7 +1632,7 @@ static int amdgpu_notify_freesync(struct drm_device *dev, 
void *data,
new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
 
-   dm_new_crtc_state->freesync_enabled = enable;
+   dm_new_crtc_state->base.variable_refresh = enable;
}
 
ret = drm_atomic_commit(state);
@@ -2541,7 +2541,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
 
update_stream_signal(stream);
 
-   if (dm_state && dm_state->freesync_capable)
+   if (dm_state && dm_state->base.variable_refresh_capable)
stream->ignore_msa_timing_param = true;
 finish:
if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL)
@@ -2611,7 +2611,6 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
 
state->adjust = cur->adjust;
state->vrr_infopacket = cur->vrr_infopacket;
-   state->freesync_enabled = cur->freesync_enabled;
 
/* TODO Duplicate dc_stream after objects are stream object is 
flattened */
 
@@ -2722,12 +2721,6 @@ int amdgpu_dm_connector_atomic_set_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
dm_new_state->underscan_enable = val;
ret = 0;
-   } else if (property == adev->mode_info.freesync_property) {
-   dm_new_state->freesync_enable = val;
-   ret = 0;
-   } else if (property == adev->mode_info.freesync_capable_property) {
-   dm_new_state->freesync_capable = val;
-   ret = 0;
}
 
return ret;
@@ -2770,12 +2763,6 @@ int amdgpu_dm_connector_atomic_get_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
*val = dm_state->underscan_enable;
ret = 0;
-   } else if (property == adev->mode_info.freesync_property) {
-   *val = dm_state->freesync_enable;
-   ret = 0;
-   } else if (property == adev->mode_info.freesync_capable_property) {
-   *val = dm_state->freesync_capable;
-   ret = 0;
}
return ret;
 }
@@ -2839,9 +2826,6 @@ amdgpu_dm_connector_atomic_duplicate_state(struct 
drm_connector *connector)
 
__drm_atomic_helper_connector_duplicate_state(connector, 
_state->base);
 
-   new_state->freesync_capable = state->freesync_capable;
-   new_state->freesync_enable = state->freesync_enable;
-
return _state->base;
 }
 
@@ -3602,10 +3586,8 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
 
if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
-   drm_object_attach_property(>base.base,
-   adev->mode_info.freesync_property, 0);
-   drm_object_attach_property(>base.base,
-   adev->mode_info.freesync_capable_property, 0);
+   drm_connector_attach_variable_refresh_properties(
+   >base);
}
 }
 
@@ -4123,7 +4105,8 @@ static bool commit_planes_to_stream(
stream_update->dst = dc_stream->dst;
stream_update->out_transfer_func = dc_stream->out_transfer_func;
 
-   if (dm_new_crtc_state->freesync_enabled != 
dm_old_crtc_state->freesync_enabled) {
+   if (dm_new_crtc_state->base.variable_refresh !=
+   dm_old_crtc_state->base.variable_refresh) {
stream_update->vrr_infopacket = _stream->vrr_infopacket;
stream_update->adjust = _stream->adjust;
}
@@ -4695,9 +4678,9 @@ void set_freesync_on_

[PATCH 8/9] drm/amd/display: Drop FreeSync ioctl notification support

2018-09-11 Thread Nicholas Kazlauskas
This is no longer needed with the addition of the DRM properties.

The base driver correctly checks that notify_freesync is non-null before
calling so there shouldn't be any null pointer dereferences as a result
of this.

Change-Id: If0833b201c81303ca4062393e873faf3ef7c143b
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 71 ---
 1 file changed, 71 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 d28bab0f4657..c9de8f555c6a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1581,76 +1581,6 @@ static void dm_bandwidth_update(struct amdgpu_device 
*adev)
/* TODO: implement later */
 }
 
-static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
-   struct drm_file *filp)
-{
-   struct drm_amdgpu_freesync *args = data;
-   struct drm_atomic_state *state;
-   struct drm_modeset_acquire_ctx ctx;
-   struct drm_crtc *crtc;
-   struct drm_connector *connector;
-   struct drm_connector_state *old_con_state, *new_con_state;
-   int ret = 0;
-   uint8_t i;
-   bool enable = false;
-
-   if (args->op == AMDGPU_FREESYNC_FULLSCREEN_ENTER)
-   enable = true;
-
-   drm_modeset_acquire_init(, 0);
-
-   state = drm_atomic_state_alloc(dev);
-   if (!state) {
-   ret = -ENOMEM;
-   goto out;
-   }
-   state->acquire_ctx = 
-
-retry:
-   drm_for_each_crtc(crtc, dev) {
-   ret = drm_atomic_add_affected_connectors(state, crtc);
-   if (ret)
-   goto fail;
-
-   /* TODO rework amdgpu_dm_commit_planes so we don't need this */
-   ret = drm_atomic_add_affected_planes(state, crtc);
-   if (ret)
-   goto fail;
-   }
-
-   for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
-   struct dm_connector_state *dm_new_con_state = 
to_dm_connector_state(new_con_state);
-   struct drm_crtc_state *new_crtc_state;
-   struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
-   struct dm_crtc_state *dm_new_crtc_state;
-
-   if (!acrtc) {
-   ASSERT(0);
-   continue;
-   }
-
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
-   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
-
-   dm_new_crtc_state->base.variable_refresh = enable;
-   }
-
-   ret = drm_atomic_commit(state);
-
-fail:
-   if (ret == -EDEADLK) {
-   drm_atomic_state_clear(state);
-   drm_modeset_backoff();
-   goto retry;
-   }
-
-   drm_atomic_state_put(state);
-
-out:
-   drm_modeset_drop_locks();
-   drm_modeset_acquire_fini();
-   return ret;
-}
 
 static const struct amdgpu_display_funcs dm_display_funcs = {
.bandwidth_update = dm_bandwidth_update, /* called unconditionally */
@@ -1664,7 +1594,6 @@ static const struct amdgpu_display_funcs dm_display_funcs 
= {
dm_crtc_get_scanoutpos,/* called unconditionally */
.add_encoder = NULL, /* VBIOS parsing. DAL does it. */
.add_connector = NULL, /* VBIOS parsing. DAL does it. */
-   .notify_freesync = amdgpu_notify_freesync,
 
 };
 
-- 
2.17.1

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


[PATCH 9/9] drm/amdgpu: Drop unneeded freesync properties from amdpgu

2018-09-11 Thread Nicholas Kazlauskas
With the introduction of new properties in DRM these amdgpu driver
specific ones are no longer necessary.

Change-Id: Idc88f2e3e036aacc8fe726b15db03d900e509e7c
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 12 
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h|  4 
 2 files changed, 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 7d6a36bca9dd..4f2928e91f9c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -626,18 +626,6 @@ int amdgpu_display_modeset_create_props(struct 
amdgpu_device *adev)
 "dither",
 amdgpu_dither_enum_list, sz);
 
-   if (amdgpu_device_has_dc_support(adev)) {
-   adev->mode_info.freesync_property =
-   drm_property_create_bool(adev->ddev, 0, "freesync");
-   if (!adev->mode_info.freesync_property)
-   return -ENOMEM;
-   adev->mode_info.freesync_capable_property =
-   drm_property_create_bool(adev->ddev,
-0,
-"freesync_capable");
-   if (!adev->mode_info.freesync_capable_property)
-   return -ENOMEM;
-   }
 
return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index f91a9bdcd63c..b9e9e8b02fb7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -339,10 +339,6 @@ struct amdgpu_mode_info {
struct drm_property *audio_property;
/* FMT dithering */
struct drm_property *dither_property;
-   /* it is used to allow enablement of freesync mode */
-   struct drm_property *freesync_property;
-   /* it is used to know about display capability of freesync mode */
-   struct drm_property *freesync_capable_property;
/* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size;
-- 
2.17.1

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


[PATCH xf86-video-amdgpu 6/6] Replace amdgpu ioctl with CRTC properties for enabling FreeSync

2018-09-11 Thread Nicholas Kazlauskas
The support for per-CRTC variable refresh control via DRM
properties means that the driver specific FreeSync IOCTL can be
replaced.

In order to accomodate this new behavior existing changes to how
and when FreeSync is enabled/disabled was needed.

There are 3 behavioral differences this patch introduces:

1. FreeSync clients are considered fullscreen when they cover an
entire CRTC instead of the X Screen.

This allows FreeSync to be enabled in multi-monitor situations.

2. FreeSync is enabled immediately upon receiving the FreeSync request.

This replaces the deferred enablment on flip. The CRTC can be targeted
directly and there's no need to wait until the flip. The DC kernel
driver will take care of enabling/disabling on the next flip.

The caveat here is that some windows (like desktop compositor surfaces)
will have FreeSync enabled if they are not explicitly blacklisted
(ie. in mesa).

Since these typically didn't change position or size they were ignored
previously. There was a bug here, however - if you hotplug monitors
in certain configurations then you'd be stuck with FreeSync enabled on
the Desktop until reboot.

3. Freesync is disabled when the Drawable's Window is destroyed instead
of when the client resource is removed.

The need for allocation of a resource to handle this is unecessary
when we get callbacks for each Window being destroyed on the screen.

The remaining changes are small cleanups that shouldn't affect
functional behavior.

Signed-off-by: Nicholas Kazlauskas 
---
 src/amdgpu_dri2.c  |  26 ---
 src/amdgpu_drv.h   |   5 +-
 src/amdgpu_extension.c | 149 +++--
 src/amdgpu_extension.h |   7 +-
 src/amdgpu_kms.c   |  45 -
 src/amdgpu_present.c   |   8 ---
 src/drmmode_display.c  |  88 
 src/drmmode_display.h  |   1 +
 8 files changed, 209 insertions(+), 120 deletions(-)

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index c14ffb1..17eb287 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -528,14 +528,6 @@ amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr 
client,
xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
   "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info);
 
-   if (info->allow_freesync &&
-   info->freesync_client &&
-   info->freesync_enabled == FALSE) {
-   AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
-   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE))
-   info->freesync_enabled = TRUE;
-   }
-
/* Page flip the full screen buffer */
back_priv = back->driverPrivate;
if (amdgpu_do_pageflip(scrn, client, back_priv->pixmap,
@@ -689,8 +681,6 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr 
crtc, uint32_t seq,
 {
DRI2FrameEventPtr event = event_data;
ScrnInfoPtr scrn = crtc->scrn;
-   AMDGPUInfoPtr info = AMDGPUPTR(scrn);
-   AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
DrawablePtr drawable;
int status;
int swap_type;
@@ -721,13 +711,6 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr 
crtc, uint32_t seq,
}
/* else fall through to exchange/blit */
case DRI2_SWAP:
-   if (info->allow_freesync &&
-   info->freesync_client &&
-   info->freesync_enabled == TRUE) {
-   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
-   info->freesync_enabled = FALSE;
-   }
-
if (DRI2CanExchange(drawable) &&
can_exchange(scrn, drawable, event->front, event->back)) {
amdgpu_dri2_exchange_buffers(drawable, event->front,
@@ -1094,8 +1077,6 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, 
DrawablePtr draw,
 {
ScreenPtr screen = draw->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-   AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
-   AMDGPUInfoPtr info = AMDGPUPTR(scrn);
xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
uint32_t msc_delta;
drmVBlankSeqType type;
@@ -1268,13 +1249,6 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, 
DrawablePtr draw,
return TRUE;
 
 blit_fallback:
-   if (info->allow_freesync &&
-   info->freesync_client &&
-   info->freesync_enabled == TRUE) {
-   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
-   info->freesync_enabled = FALSE;
-   }
-
if (swap_info) {
swap_info->type = DRI2_SWAP;
amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 71274d1..b6425d7 100644
--- a/src/amdgp

[PATCH xf86-video-amdgpu 5/6] Do not issue freesync ioctl from present unflip

2018-09-11 Thread Nicholas Kazlauskas
From: Hawking Zhang 

It prefers that freesync is enable/disable per client lifecycle
rather than per flip. With the patch, freesync will be disabled
when clientgone or switch to windowed mode.

Change-Id: I2c725bd045c4855f9e1436f0791755b0a47a6ecc
Signed-off-by: Hawking Zhang 
Reviewed-by: Flora Cui 
---
 src/amdgpu_present.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
index 66d264c..9ed000b 100644
--- a/src/amdgpu_present.c
+++ b/src/amdgpu_present.c
@@ -371,12 +371,6 @@ amdgpu_present_unflip(ScreenPtr screen, uint64_t event_id)
if (!amdgpu_present_check_unflip(scrn))
goto modeset;
 
-   if (info->freesync_capable_client &&
-   info->freesync_enabled == TRUE) {
-   if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, 
FALSE))
-   info->freesync_enabled = FALSE;
-   }
-
event = calloc(1, sizeof(struct amdgpu_present_vblank_event));
if (!event) {
ErrorF("%s: calloc failed, display might freeze\n", __func__);
-- 
2.18.0

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


[PATCH xf86-video-amdgpu 4/6] Handle Alt+Tab case when freesync enabled in steam client v2

2018-09-11 Thread Nicholas Kazlauskas
From: Hawking Zhang 

v2:
fix ddx build warning unused var

The change supports the following scenario when freesync enabled for steam game
1). use Alt+Tab to run-time switch between windowed mode and fullscreen mode
2). use option setting to switch between windowed mode and fullscreen mode
Also verified on unigine heaven via setting check/un-check fullscreen

Signed-off-by: Hawking Zhang 
Reviewed-by: Flora Cui 
---
 src/amdgpu_dri2.c  |  9 ++---
 src/amdgpu_drv.h   |  8 ++--
 src/amdgpu_extension.c | 25 +++--
 src/amdgpu_kms.c   | 41 +
 src/amdgpu_present.c   |  3 ++-
 5 files changed, 70 insertions(+), 16 deletions(-)

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 8c601c8..c14ffb1 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -528,7 +528,8 @@ amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr 
client,
xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
   "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info);
 
-   if (info->freesync_capable_client &&
+   if (info->allow_freesync &&
+   info->freesync_client &&
info->freesync_enabled == FALSE) {
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE))
@@ -720,7 +721,8 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr 
crtc, uint32_t seq,
}
/* else fall through to exchange/blit */
case DRI2_SWAP:
-   if (info->freesync_capable_client &&
+   if (info->allow_freesync &&
+   info->freesync_client &&
info->freesync_enabled == TRUE) {
if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
info->freesync_enabled = FALSE;
@@ -1266,7 +1268,8 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, 
DrawablePtr draw,
return TRUE;
 
 blit_fallback:
-   if (info->freesync_capable_client &&
+   if (info->allow_freesync &&
+   info->freesync_client &&
info->freesync_enabled == TRUE) {
if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
info->freesync_enabled = FALSE;
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 91bb829..71274d1 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -248,6 +248,8 @@ typedef struct {
uint32_t family;
struct gbm_device *gbm;
 
+   ClipNotifyProcPtr ClipNotify;
+
Bool(*CloseScreen) (ScreenPtr pScreen);
 
void (*BlockHandler) (BLOCKHANDLER_ARGS_DECL);
@@ -304,9 +306,11 @@ typedef struct {
Bool allowPageFlip;
 
/* freesync */
-   ClientPtr freesync_capable_client;
-   uint32_t client_resource_id;
+   ClientPtr freesync_client;
+   DrawablePtr freesync_drawable;
+   XID freesync_client_id;
Bool freesync_enabled;
+   Bool allow_freesync;
 
/* cursor size */
int cursor_w;
diff --git a/src/amdgpu_extension.c b/src/amdgpu_extension.c
index ab7d6e3..33c8987 100644
--- a/src/amdgpu_extension.c
+++ b/src/amdgpu_extension.c
@@ -62,15 +62,17 @@ static int ProcAMDGPUFreesyncCapability(ClientPtr client)
client, 0, DixReadAccess);
 
if (!ret &&
-   info->freesync_capable_client == NULL &&
pDrawable->x == pDrawable->pScreen->x &&
pDrawable->y == pDrawable->pScreen->y &&
pDrawable->width == pDrawable->pScreen->width &&
pDrawable->height == pDrawable->pScreen->height) {
-   info->freesync_capable_client = client;
-   cliResId = FakeClientID(client->index);
-   if (AddResource(cliResId, RT_AMDGPUCLIENT, (void *)pScrn))
-   info->client_resource_id = cliResId;
+   if (!info->freesync_client) {
+   info->freesync_client = client;
+   cliResId = FakeClientID(client->index);
+   if (AddResource(cliResId, RT_AMDGPUCLIENT, (void 
*)pScrn))
+   info->freesync_client_id = cliResId;
+   }
+   info->freesync_drawable = pDrawable;
}
 
return client->noClientException;
@@ -162,8 +164,8 @@ void AMDGPUFreeResourceByType(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 
-   if (info->client_resource_id)
-   FreeResourceByType(info->client_resource_id,
+   if (info->freesync_client_id)
+   FreeResourceByType(info->freesync_client_id,
   RT_AMDGPUCLIENT, FALSE);
return;
 }
@@ -174,9 +176,10 @@ int AMDGPUClientGone(void *data, XID id)
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
 
-   if (id == 

[PATCH 3/9] drm/amdgpu: fill in amdgpu_dm_remove_sink_from_freesync_module

2018-09-11 Thread Nicholas Kazlauskas
From: Harry Wentland 

Add code to tear down freesync modules when disabled.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Deucher 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 40 ++-
 1 file changed, 29 insertions(+), 11 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 af6adffba788..9dad505d132f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5230,19 +5230,37 @@ void amdgpu_dm_add_sink_to_freesync_module(struct 
drm_connector *connector,
dm_con_state->freesync_capable = true;
}
}
-
-   /*
-* TODO figure out how to notify user-mode or DRM of freesync caps
-* once we figure out how to deal with freesync in an upstreamable
-* fashion
-*/
-
 }
 
 void amdgpu_dm_remove_sink_from_freesync_module(struct drm_connector 
*connector)
 {
-   /*
-* TODO fill in once we figure out how to deal with freesync in
-* an upstreamable fashion
-*/
+   struct amdgpu_dm_connector *amdgpu_dm_connector =
+   to_amdgpu_dm_connector(connector);
+   struct dm_connector_state *dm_con_state;
+   struct drm_device *dev = connector->dev;
+   struct amdgpu_device *adev = dev->dev_private;
+
+   if (!amdgpu_dm_connector->dc_sink || !adev->dm.freesync_module) {
+   DRM_ERROR("dc_sink NULL or no free_sync module.\n");
+   return;
+   }
+
+   if (!connector->state) {
+   DRM_ERROR("%s - Connector has no state", __func__);
+   return;
+   }
+
+   dm_con_state = to_dm_connector_state(connector->state);
+
+   amdgpu_dm_connector->min_vfreq = 0;
+   amdgpu_dm_connector->max_vfreq = 0;
+   amdgpu_dm_connector->pixel_clock_mhz = 0;
+
+   memset(_dm_connector->caps, 0, 
sizeof(amdgpu_dm_connector->caps));
+
+   dm_con_state->freesync_capable = false;
+
+   dm_con_state->user_enable.enable_for_gaming = false;
+   dm_con_state->user_enable.enable_for_static = false;
+   dm_con_state->user_enable.enable_for_video = false;
 }
-- 
2.17.1

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


[PATCH 5/9] drm/amdgpu/display: add freesync drm properties

2018-09-11 Thread Nicholas Kazlauskas
From: Harry Wentland 

Add connector properties for controlling freesync.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 13 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  4 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 +++
 3 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 6748cd7fc129..642b47c5f4b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -626,6 +626,19 @@ int amdgpu_display_modeset_create_props(struct 
amdgpu_device *adev)
 "dither",
 amdgpu_dither_enum_list, sz);
 
+   if (amdgpu_device_has_dc_support(adev)) {
+   adev->mode_info.freesync_property =
+   drm_property_create_bool(adev->ddev, 0, "freesync");
+   if (!adev->mode_info.freesync_property)
+   return -ENOMEM;
+   adev->mode_info.freesync_capable_property =
+   drm_property_create_bool(adev->ddev,
+0,
+"freesync_capable");
+   if (!adev->mode_info.freesync_capable_property)
+   return -ENOMEM;
+   }
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b9e9e8b02fb7..f91a9bdcd63c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -339,6 +339,10 @@ struct amdgpu_mode_info {
struct drm_property *audio_property;
/* FMT dithering */
struct drm_property *dither_property;
+   /* it is used to allow enablement of freesync mode */
+   struct drm_property *freesync_property;
+   /* it is used to know about display capability of freesync mode */
+   struct drm_property *freesync_capable_property;
/* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size;
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 d599fbfa895b..8be3028850b6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2718,6 +2718,12 @@ int amdgpu_dm_connector_atomic_set_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
dm_new_state->underscan_enable = val;
ret = 0;
+   } else if (property == adev->mode_info.freesync_property) {
+   dm_new_state->freesync_enable = val;
+   ret = 0;
+   } else if (property == adev->mode_info.freesync_capable_property) {
+   dm_new_state->freesync_capable = val;
+   ret = 0;
}
 
return ret;
@@ -2760,6 +2766,12 @@ int amdgpu_dm_connector_atomic_get_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
*val = dm_state->underscan_enable;
ret = 0;
+   } else if (property == adev->mode_info.freesync_property) {
+   *val = dm_state->freesync_enable;
+   ret = 0;
+   } else if (property == adev->mode_info.freesync_capable_property) {
+   *val = dm_state->freesync_capable;
+   ret = 0;
}
return ret;
 }
@@ -3584,6 +3596,13 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.underscan_vborder_property,
0);
 
+   if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+   connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+   drm_object_attach_property(>base.base,
+   adev->mode_info.freesync_property, 0);
+   drm_object_attach_property(>base.base,
+   adev->mode_info.freesync_capable_property, 0);
+   }
 }
 
 static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap,
-- 
2.17.1

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


[PATCH xf86-video-amdgpu 2/6] Set freesync capability when client has fullscreen size drawable

2018-09-11 Thread Nicholas Kazlauskas
From: Hawking Zhang 

OGL send freesync request to ddx driver when it makes a drawable as current
DDX driver only set the client to be freesync capable when it is a fullscreen
size one.

Change-Id: Ie25ff11f58104546c52a253d6a5f85aa62532d4d
Signed-off-by: Hawking Zhang 
Reviewed-by: Flora Cui 
---
 src/amdgpu_extension.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/amdgpu_extension.c b/src/amdgpu_extension.c
index 1c984df..eadb742 100644
--- a/src/amdgpu_extension.c
+++ b/src/amdgpu_extension.c
@@ -32,6 +32,8 @@
 #include "extnsionst.h"
 #include "resource.h"
 #include "scrnintstr.h"
+#include "dixaccess.h"
+#include "pixmap.h"
 
 #include "amdgpu_drm.h"
 #include "amdgpu_extension.h"
@@ -53,8 +55,16 @@ static int ProcAMDGPUFreesyncCapability(ClientPtr client)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
XID cliResId;
+   DrawablePtr pDrawable = NULL;
+   if (dixLookupDrawable(, (Drawable)stuff->drawable,
+ client, 0, DixReadAccess))
+   return BadValue;
 
-   if (info->freesync_capable_client == NULL) {
+   if (info->freesync_capable_client == NULL &&
+   pDrawable->x == pDrawable->pScreen->x &&
+   pDrawable->y == pDrawable->pScreen->y &&
+   pDrawable->width == pDrawable->pScreen->width &&
+   pDrawable->height == pDrawable->pScreen->height) {
info->freesync_capable_client = client;
cliResId = FakeClientID(client->index);
if (AddResource(cliResId, RT_AMDGPUCLIENT, (void *)pScrn))
-- 
2.18.0

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


[PATCH xf86-video-amdgpu 3/6] Do not fail the X request when there is just BadDrawable/BadMatch

2018-09-11 Thread Nicholas Kazlauskas
From: Hawking Zhang 

There is BadDrawable/BadMatch case for dixLookupDrawable. But DDX driver don't
need to fail the request with BadValue. Instead, only make sure the drawable is
successfully found and check its size

Change-Id: I1ca6e04d611b2d5e81a54e500c90fb1644675f67
Signed-off-by: Hawking Zhang 
Reviewed-by: Qiang Yu 
---
 src/amdgpu_extension.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/amdgpu_extension.c b/src/amdgpu_extension.c
index eadb742..ab7d6e3 100644
--- a/src/amdgpu_extension.c
+++ b/src/amdgpu_extension.c
@@ -56,11 +56,13 @@ static int ProcAMDGPUFreesyncCapability(ClientPtr client)
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
XID cliResId;
DrawablePtr pDrawable = NULL;
-   if (dixLookupDrawable(, (Drawable)stuff->drawable,
- client, 0, DixReadAccess))
-   return BadValue;
+   int ret = -1;
+
+   ret = dixLookupDrawable(, (Drawable)stuff->drawable,
+   client, 0, DixReadAccess);
 
-   if (info->freesync_capable_client == NULL &&
+   if (!ret &&
+   info->freesync_capable_client == NULL &&
pDrawable->x == pDrawable->pScreen->x &&
pDrawable->y == pDrawable->pScreen->y &&
pDrawable->width == pDrawable->pScreen->width &&
-- 
2.18.0

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


[PATCH] drm/amd/display: Use div_u64 for flip timestamp ns to ms

2018-12-19 Thread Nicholas Kazlauskas
Resolves __udivdi3 missing errors when building for i386.

Fixes: 6378ef012ddc ("drm/amd/display: Add below the range support for 
FreeSync")

Change-Id: I4ded5790160054e6908367f20a63257225517714
Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e16e62139ec3..920649332055 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4550,6 +4550,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
  struct dc_state *state)
 {
unsigned long flags;
+   uint64_t timestamp_ns;
uint32_t target_vblank;
int r, vpos, hpos;
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
@@ -4612,7 +4613,9 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
addr.address.grph.addr.low_part = lower_32_bits(afb->address);
addr.address.grph.addr.high_part = upper_32_bits(afb->address);
addr.flip_immediate = async_flip;
-   addr.flip_timestamp_in_us = ktime_get_ns() / 1000;
+
+   timestamp_ns = ktime_get_ns();
+   addr.flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
 
 
if (acrtc->base.state->event)
-- 
2.17.1

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


[PATCH] drm/amd/display - Don't leak memory when updating streams

2019-01-28 Thread Nicholas Kazlauskas
[Why]
The flip and full structures were allocated but never freed.

[How]
Free them at the end of the function. There's a small behavioral
change here with the function returning early if the allocation fails
but we wouldn't should be doing anything in that case anyway.

Fixes: c00e0cc0fdc0 ("drm/amd/display: Call into DC once per multiplane flip")
Fixes: ea39594e0855 ("drm/amd/display: Perform plane updates only when needed")

Cc: Michel Dänzer 
Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e551183784fb..78c89da47a33 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4760,8 +4760,10 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
flip = kzalloc(sizeof(*flip), GFP_KERNEL);
full = kzalloc(sizeof(*full), GFP_KERNEL);
 
-   if (!flip || !full)
+   if (!flip || !full) {
dm_error("Failed to allocate update bundles\n");
+   goto cleanup;
+   }
 
/* update planes when needed */
for_each_oldnew_plane_in_state(state, plane, old_plane_state, 
new_plane_state, i) {
@@ -4985,6 +4987,10 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
 dc_state);
mutex_unlock(>dc_lock);
}
+
+cleanup:
+   kfree(flip);
+   kfree(full);
 }
 
 /*
-- 
2.17.1

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


[PATCH] drm/amd/display: Remove semicolon from to_dm_plane_state definition

2019-03-25 Thread Nicholas Kazlauskas
The extra ; in the macro definition creates an empty statement
preventing any variable declarations from occuring after
any use of to_dm_plane_state(...).

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 87ca5746f861..94b77488a0e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -57,7 +57,7 @@ struct amdgpu_hpd;
 #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base)
 #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, 
base)
 
-#define to_dm_plane_state(x)   container_of(x, struct dm_plane_state, base);
+#define to_dm_plane_state(x)   container_of(x, struct dm_plane_state, base)
 
 #define AMDGPU_MAX_HPD_PINS 6
 #define AMDGPU_MAX_CRTCS 6
-- 
2.17.1

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

Re: [PATCH 07/18] drm/amd/display: Create overlay planes

2019-02-27 Thread Nicholas Kazlauskas
On 2019-02-26 11:03 p.m., Vishwakarma, Pratik wrote:
> 
> On 2/26/2019 4:16 AM, Bhawanpreet Lakha wrote:
>> From: Nicholas Kazlauskas 
>>
>> [Why]
>> Raven has support for combining pipes for DRM_PLANE_TYPE_OVERLAY use
>> but no overlays are exposed to userspace.
>>
>> [How]
>> Expose overlay planes based on DC plane caps.
>>
>> If all the pipes are in use then the atomic commits can fail, but this
>> is expected behavior for userspace.
>>
>> Only support RGB on overlays for now.
>>
>> Change-Id: Idca78fafefd7ccb2bd5f1a05901d1c9da1a2decb
>> Signed-off-by: Nicholas Kazlauskas 
>> Reviewed-by: Tony Cheng 
>> Acked-by: Bhawanpreet Lakha 
>> ---
>>.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 51 ---
>>1 file changed, 44 insertions(+), 7 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 dc7124e60b27..25cd7970114d 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -1892,7 +1892,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
>> amdgpu_device *adev)
>>  struct amdgpu_encoder *aencoder = NULL;
>>  struct amdgpu_mode_info *mode_info = >mode_info;
>>  uint32_t link_cnt;
>> -int32_t primary_planes;
>> +int32_t overlay_planes, primary_planes, total_planes;
>>  enum dc_connection_type new_connection_type = dc_connection_none;
>>
>>  link_cnt = dm->dc->caps.max_links;
>> @@ -1901,9 +1901,29 @@ static int amdgpu_dm_initialize_drm_device(struct 
>> amdgpu_device *adev)
>>  return -EINVAL;
>>  }
>>
>> +/*
>> + * Determine the number of overlay planes supported.
>> + * Only support DCN for now, and cap so we don't encourage
>> + * userspace to use up all the planes.
>> + */
>> +overlay_planes = 0;
>> +
>> +for (i = 0; i < dm->dc->caps.max_planes; ++i) {
>> +struct dc_plane_cap *plane = >dc->caps.planes[i];
>> +
>> +if (plane->type == DC_PLANE_TYPE_DCN_UNIVERSAL &&
>> +plane->blends_with_above && plane->blends_with_below &&
>> +plane->supports_argb)
>> +overlay_planes += 1;
>> +}
>> +
>> +overlay_planes = min(overlay_planes, 1);
>> +
>>  /* There is one primary plane per CRTC */
>>  primary_planes = dm->dc->caps.max_streams;
>> -ASSERT(primary_planes < AMDGPU_MAX_PLANES);
>> +
>> +total_planes = primary_planes + overlay_planes;
>> +ASSERT(total_planes < AMDGPU_MAX_PLANES);
>>
>>  /*
>>   * Initialize primary planes, implicit planes for legacy IOCTLS.
>> @@ -1917,6 +1937,20 @@ static int amdgpu_dm_initialize_drm_device(struct 
>> amdgpu_device *adev)
>>  }
>>  }
>>
>> +/*
>> + * Initialize overlay planes, index starting after primary planes.
>> + * These planes have a higher DRM index than the primary planes since
>> + * they should be considered as having a higher z-order.
>> + * Order is reversed to match iteration order in atomic check.
>> + */
>> +for (i = (overlay_planes - 1); i >= 0; i--) {
>> +if (initialize_plane(dm, mode_info, primary_planes + i,
>> + DRM_PLANE_TYPE_OVERLAY)) {
>> +DRM_ERROR("KMS: Failed to initialize overlay plane\n");
>> +goto fail;
>> +}
>> +}
>> +
> Wouldn't the above change affect dm_update_planes_state which uses
> for_each_oldnew_plane_in_state_reverse to add planes in reverse order?

It's intentional for correct z-ordering. When adding planes to DC 
they're added from highest z-order to lowest z-order.

These overlay planes have a higher DRM index than the primary planes so 
they'll be added first.

The underlay planes from before had a lower DRM index than the primary 
planes so they were added last. This also was required with underlays 
since DC would only acquire the underlay pipe last as well.

Nicholas Kazlauskas

>>  for (i = 0; i < dm->dc->caps.max_streams; i++)
>>  if (amdgpu_dm_crtc_init(dm, mode_info->planes[i], i)) {
>>  DRM_ERROR("KMS: Failed to initialize crtc\n");
>> @@ -3876,9 +3910,12 @@ static const uint32_t rgb_formats

[PATCH] drm/amdgpu: Bump amdgpu version for per-flip plane tiling updates

2019-02-28 Thread Nicholas Kazlauskas
To help xf86-video-amdgpu and mesa know DC supports updating the
tiling attributes for a framebuffer per-flip.

Cc: Michel Dänzer 
Cc: Marek Olšák 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 223013ef8466..ae4e3eeb4ae2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -74,9 +74,10 @@
  * - 3.28.0 - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES
  * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID
  * - 3.30.0 - Add AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE.
+ * - 3.31.0 - Add support for per-flip tiling attribute changes with DC
  */
 #define KMS_DRIVER_MAJOR   3
-#define KMS_DRIVER_MINOR   30
+#define KMS_DRIVER_MINOR   31
 #define KMS_DRIVER_PATCHLEVEL  0
 
 int amdgpu_vram_limit = 0;
-- 
2.17.1

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

[PATCH] drm/amd/display: Drop atomic_obj_lock for private obj

2019-03-05 Thread Nicholas Kazlauskas
[Why]
New DRM versions manage locking for private objects for us, so this
is no longer needed.

This also prevents a WARN_ON from occurring when the private object is
duplicated during the forced atomic commit that occurs from the HPD
handler.

The HPD handler calls drm_modeset_lock_all before the forced commit
and if the private object is duplicated then the
DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire) warning will be triggered
since we're trying to lock something when everything should have
already been locked.

[How]
Drop the lock and let DRM manage this.

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 --
 2 files changed, 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 bdbc8006d9ea..e6d817b467e7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1569,15 +1569,10 @@ static int dm_atomic_get_state(struct drm_atomic_state 
*state,
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_display_manager *dm = >dm;
struct drm_private_state *priv_state;
-   int ret;
 
if (*dm_state)
return 0;
 
-   ret = drm_modeset_lock(>atomic_obj_lock, state->acquire_ctx);
-   if (ret)
-   return ret;
-
priv_state = drm_atomic_get_private_obj_state(state, >atomic_obj);
if (IS_ERR(priv_state))
return PTR_ERR(priv_state);
@@ -1684,8 +1679,6 @@ static int amdgpu_dm_mode_config_init(struct 
amdgpu_device *adev)
 
adev->ddev->mode_config.fb_base = adev->gmc.aper_base;
 
-   drm_modeset_lock_init(>dm.atomic_obj_lock);
-
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 74e3a52f4f71..12e3b697ccef 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -132,8 +132,6 @@ struct amdgpu_display_manager {
 */
struct drm_private_obj atomic_obj;
 
-   struct drm_modeset_lock atomic_obj_lock;
-
/**
 * @dc_lock:
 *
-- 
2.17.1

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

[PATCH] drm/amd/display: Don't ASSERT when total_planes == AMDGPU_MAX_PLANES

2019-03-05 Thread Nicholas Kazlauskas
[Why]
Can happen on ASICs with 6 planes, but this isn't a bug since we haven't
written outside the array.

[How]
Use <= instead of <.

Cc: Leo Li 
Cc: Michel Dänzer 
Reported-by: Michel Dänzer 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index bdbc8006d9ea..b1208883da1b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1923,7 +1923,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
primary_planes = dm->dc->caps.max_streams;
 
total_planes = primary_planes + overlay_planes;
-   ASSERT(total_planes < AMDGPU_MAX_PLANES);
+   ASSERT(total_planes <= AMDGPU_MAX_PLANES);
 
/*
 * Initialize primary planes, implicit planes for legacy IOCTLS.
-- 
2.17.1

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

[PATCH] drm/amd/display: Only put primary planes into the mode_info->planes list

2019-03-14 Thread Nicholas Kazlauskas
We want DRM planes to be initialized in the following order:

- primary planes
- overlay planes
- cursor planes

to support existing userspace expectations for plane z-ordering. This
means that we also need to register CRTCs after all planes have been
initialized since overlay planes can be placed on any CRTC.

So the only reason why we have the mode_info->planes list is to
remember the primary planes for use later when we need to register
the CRTC.

Overlay planes have no purpose being in this list. DRM will cleanup
any planes that we've registered for us, so the only planes that need to
be explicitly cleaned up are the ones that have failed to register.

By dropping the explicit free on every plane in the mode_info->planes
list this patch also fixes a double-free in the case where we fail to
initialize only some of the planes.

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 +--
 1 file changed, 9 insertions(+), 10 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 cde0da3ae964..f770de36121f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1818,8 +1818,6 @@ static int initialize_plane(struct amdgpu_display_manager 
*dm,
int ret = 0;
 
plane = kzalloc(sizeof(struct drm_plane), GFP_KERNEL);
-   mode_info->planes[plane_id] = plane;
-
if (!plane) {
DRM_ERROR("KMS: Failed to allocate plane\n");
return -ENOMEM;
@@ -1836,13 +1834,17 @@ static int initialize_plane(struct 
amdgpu_display_manager *dm,
if (plane_id >= dm->dc->caps.max_streams)
possible_crtcs = 0xff;
 
-   ret = amdgpu_dm_plane_init(dm, mode_info->planes[plane_id], 
possible_crtcs);
+   ret = amdgpu_dm_plane_init(dm, plane, possible_crtcs);
 
if (ret) {
DRM_ERROR("KMS: Failed to initialize plane\n");
+   kfree(plane);
return ret;
}
 
+   if (mode_info)
+   mode_info->planes[plane_id] = plane;
+
return ret;
 }
 
@@ -1885,7 +1887,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
struct amdgpu_encoder *aencoder = NULL;
struct amdgpu_mode_info *mode_info = >mode_info;
uint32_t link_cnt;
-   int32_t overlay_planes, primary_planes, total_planes;
+   int32_t overlay_planes, primary_planes;
enum dc_connection_type new_connection_type = dc_connection_none;
 
link_cnt = dm->dc->caps.max_links;
@@ -1914,9 +1916,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
/* There is one primary plane per CRTC */
primary_planes = dm->dc->caps.max_streams;
-
-   total_planes = primary_planes + overlay_planes;
-   ASSERT(total_planes <= AMDGPU_MAX_PLANES);
+   ASSERT(primary_planes <= AMDGPU_MAX_PLANES);
 
/*
 * Initialize primary planes, implicit planes for legacy IOCTLS.
@@ -1937,7 +1937,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 * Order is reversed to match iteration order in atomic check.
 */
for (i = (overlay_planes - 1); i >= 0; i--) {
-   if (initialize_plane(dm, mode_info, primary_planes + i,
+   if (initialize_plane(dm, NULL, primary_planes + i,
 DRM_PLANE_TYPE_OVERLAY)) {
DRM_ERROR("KMS: Failed to initialize overlay plane\n");
goto fail;
@@ -2041,8 +2041,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 fail:
kfree(aencoder);
kfree(aconnector);
-   for (i = 0; i < primary_planes; i++)
-   kfree(mode_info->planes[i]);
+
return -EINVAL;
 }
 
-- 
2.17.1

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

[PATCH] drm/amd/display: Fix plane address updates for video surface formats

2019-03-11 Thread Nicholas Kazlauskas
[Why]
For new DC planes the correct plane address fields are filled based
on whether the plane had a graphics or video format.

However, when we perform stream and plane updates using DC we only ever
fill in the graphics format fields. This causing corruption and hangs
when using video surface formats like NV12 for planes.

[How]
Use the same logic everywhere we update dc_plane_address - always
fill in the correct fields based on the surface format type.

There are 3 places this is done:

- Atomic check, during DC plane creation
- Atomic commit, during plane prepare_fb
- Atomic commit tail, during amdgpu_dm_commit_planes

We use the fill_plane_tiling_attributes in all 3 locations and it
already needs the address to update DCC attributes, so the surface
address update logic can be moved into this helper.

Cc: Leo Li 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 57 +--
 1 file changed, 26 insertions(+), 31 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 59a8045c9e2a..e0c0621f40d4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2457,6 +2457,27 @@ fill_plane_tiling_attributes(struct amdgpu_device *adev,
 
memset(tiling_info, 0, sizeof(*tiling_info));
memset(dcc, 0, sizeof(*dcc));
+   memset(address, 0, sizeof(*address));
+
+   if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+   address->type = PLN_ADDR_TYPE_GRAPHICS;
+   address->grph.addr.low_part = lower_32_bits(afb->address);
+   address->grph.addr.high_part = upper_32_bits(afb->address);
+   } else {
+   const struct drm_framebuffer *fb = >base;
+   uint64_t awidth = ALIGN(fb->width, 64);
+   uint64_t chroma_addr = afb->address + awidth * fb->height;
+
+   address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
+   address->video_progressive.luma_addr.low_part =
+   lower_32_bits(afb->address);
+   address->video_progressive.luma_addr.high_part =
+   upper_32_bits(afb->address);
+   address->video_progressive.chroma_addr.low_part =
+   lower_32_bits(chroma_addr);
+   address->video_progressive.chroma_addr.high_part =
+   upper_32_bits(chroma_addr);
+   }
 
/* Fill GFX8 params */
if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 
DC_ARRAY_2D_TILED_THIN1) {
@@ -2571,7 +2592,6 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
memset(_state->address, 0, sizeof(plane_state->address));
 
if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
-   plane_state->address.type = PLN_ADDR_TYPE_GRAPHICS;
plane_state->plane_size.grph.surface_size.x = 0;
plane_state->plane_size.grph.surface_size.y = 0;
plane_state->plane_size.grph.surface_size.width = fb->width;
@@ -2583,7 +2603,7 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
 
} else {
awidth = ALIGN(fb->width, 64);
-   plane_state->address.type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
+
plane_state->plane_size.video.luma_size.x = 0;
plane_state->plane_size.video.luma_size.y = 0;
plane_state->plane_size.video.luma_size.width = awidth;
@@ -3738,10 +3758,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct drm_gem_object *obj;
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
-   uint64_t chroma_addr = 0;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
-   uint64_t tiling_flags, dcc_address;
-   unsigned int awidth;
+   uint64_t tiling_flags;
uint32_t domain;
int r;
 
@@ -3794,29 +3812,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
dm_plane_state_old->dc_state != 
dm_plane_state_new->dc_state) {
struct dc_plane_state *plane_state = 
dm_plane_state_new->dc_state;
 
-   if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
-   plane_state->address.grph.addr.low_part = 
lower_32_bits(afb->address);
-   plane_state->address.grph.addr.high_part = 
upper_32_bits(afb->address);
-
-   dcc_address =
-   get_dcc_address(afb->address, tiling_flags);
-   plane_state->address.grph.meta_addr.low_part =
-   lower_32_bits(dcc_address);
-   plane_state->address.grph.meta_addr.hig

[PATCH] drm/amd/display: Respect DRM framebuffer info for video surfaces

2019-03-13 Thread Nicholas Kazlauskas
[Why]
Incorrect hardcoded assumptions are made regarding luma and chroma
alignment. The actual values set for the DRM framebuffer should be used
when programming the address.

[How]
Respect the given pitch for both luma and chroma planes - it's not like
we can force the alignment to anything else at this point anyway.

Use the FB offset for the chroma planes directly. DRM already
provides this to us so there's no need to calculate it manually.

While we don't actually use the chroma surface size parameters on Raven,
these should have technically been fb->width / 2 and fb->height / 2
since the chroma plane is half size of the luma plane for NV12.

Leave a TODO indicating that those should be set based on the actual
surface format instead since this is only correct for YUV420 formats.

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +--
 1 file changed, 10 insertions(+), 11 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 cde0da3ae964..5f1e23ba75e1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2465,8 +2465,7 @@ fill_plane_tiling_attributes(struct amdgpu_device *adev,
address->grph.addr.high_part = upper_32_bits(afb->address);
} else {
const struct drm_framebuffer *fb = >base;
-   uint64_t awidth = ALIGN(fb->width, 64);
-   uint64_t chroma_addr = afb->address + awidth * fb->height;
+   uint64_t chroma_addr = afb->address + fb->offsets[1];
 
address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
address->video_progressive.luma_addr.low_part =
@@ -2542,7 +2541,6 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
 const struct amdgpu_framebuffer 
*amdgpu_fb)
 {
uint64_t tiling_flags;
-   unsigned int awidth;
const struct drm_framebuffer *fb = _fb->base;
int ret = 0;
struct drm_format_name_buf format_name;
@@ -2602,20 +2600,21 @@ static int fill_plane_attributes_from_fb(struct 
amdgpu_device *adev,
plane_state->color_space = COLOR_SPACE_SRGB;
 
} else {
-   awidth = ALIGN(fb->width, 64);
-
plane_state->plane_size.video.luma_size.x = 0;
plane_state->plane_size.video.luma_size.y = 0;
-   plane_state->plane_size.video.luma_size.width = awidth;
+   plane_state->plane_size.video.luma_size.width = fb->width;
plane_state->plane_size.video.luma_size.height = fb->height;
-   /* TODO: unhardcode */
-   plane_state->plane_size.video.luma_pitch = awidth;
+   plane_state->plane_size.video.luma_pitch =
+   fb->pitches[0] / fb->format->cpp[0];
 
plane_state->plane_size.video.chroma_size.x = 0;
plane_state->plane_size.video.chroma_size.y = 0;
-   plane_state->plane_size.video.chroma_size.width = awidth;
-   plane_state->plane_size.video.chroma_size.height = fb->height;
-   plane_state->plane_size.video.chroma_pitch = awidth / 2;
+   /* TODO: set these based on surface format */
+   plane_state->plane_size.video.chroma_size.width = fb->width / 2;
+   plane_state->plane_size.video.chroma_size.height = fb->height / 
2;
+
+   plane_state->plane_size.video.chroma_pitch =
+   fb->pitches[1] / fb->format->cpp[1];
 
/* TODO: unhardcode */
plane_state->color_space = COLOR_SPACE_YCBCR709;
-- 
2.17.1

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

[PATCH] drm/amdgpu: Clear VRAM for DRM dumb_create buffers

2019-03-08 Thread Nicholas Kazlauskas
The dumb_create API isn't intended for high performance rendering
and it's more useful for userspace (ie. IGT) to have them precleared.

The bonus here is that we also won't needlessly leak whatever was
previously in VRAM, but it also probably wasn't sensitive if it was
going through this API.

Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index fcaaac30e84b..a58072bbc9b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -743,7 +743,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
domain = amdgpu_bo_get_preferred_pin_domain(adev,
amdgpu_display_supported_domains(adev));
r = amdgpu_gem_object_create(adev, args->size, 0, domain,
-AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+AMDGPU_GEM_CREATE_VRAM_CLEARED,
 ttm_bo_type_device, NULL, );
if (r)
return -ENOMEM;
-- 
2.17.1

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

[PATCH] drm/amdgpu: Only clear dumb buffers if ring is enabled

2019-03-11 Thread Nicholas Kazlauskas
The buffers should be cleared when possible but we also don't want
buffer creation to fail in the rare case where the ring isn't ready
during the call. This could happen during some suspend/resume sequences.

Cc: Christian König 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a58072bbc9b8..9ee8d7a3c6d4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -733,18 +733,25 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
struct amdgpu_device *adev = dev->dev_private;
struct drm_gem_object *gobj;
uint32_t handle;
+   u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
u32 domain;
int r;
 
+   /*
+* The buffer returned from this function should be cleared, but
+* it can only be done if the ring is enabled or we'll fail to
+* create the buffer.
+*/
+   if (adev->mman.buffer_funcs_enabled)
+   flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
+
args->pitch = amdgpu_align_pitch(adev, args->width,
 DIV_ROUND_UP(args->bpp, 8), 0);
args->size = (u64)args->pitch * args->height;
args->size = ALIGN(args->size, PAGE_SIZE);
domain = amdgpu_bo_get_preferred_pin_domain(adev,
amdgpu_display_supported_domains(adev));
-   r = amdgpu_gem_object_create(adev, args->size, 0, domain,
-AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
-AMDGPU_GEM_CREATE_VRAM_CLEARED,
+   r = amdgpu_gem_object_create(adev, args->size, 0, domain, flags,
 ttm_bo_type_device, NULL, );
if (r)
return -ENOMEM;
-- 
2.17.1

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

[PATCH] drm/amd/display: Only allow VRR when vrefresh is within supported range

2019-03-21 Thread Nicholas Kazlauskas
[Why]
Black screens or artifacting can occur when enabling FreeSync outside
of the supported range of the monitor. This can happen since the
supported range isn't always the min/max vrefresh range available for
the monitor.

[How]
There was previously a fix that prevented this from happening in the
low range but it didn't cover the upper range. Expand the condition
to include both.

Cc: Sun peng Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 01a46119512b..5b7a85e28fab 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5551,9 +5551,11 @@ static void get_freesync_config_for_crtc(
struct amdgpu_dm_connector *aconnector =
to_amdgpu_dm_connector(new_con_state->base.connector);
struct drm_display_mode *mode = _crtc_state->base.mode;
+   int vrefresh = drm_mode_vrefresh(mode);
 
new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
-   aconnector->min_vfreq <= drm_mode_vrefresh(mode);
+   vrefresh >= aconnector->min_vfreq &&
+   vrefresh <= aconnector->max_vfreq;
 
if (new_crtc_state->vrr_supported) {
new_crtc_state->stream->ignore_msa_timing_param = true;
-- 
2.17.1

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

[PATCH] drm/amd/display: Initialize stream_update with memset

2019-03-22 Thread Nicholas Kazlauskas
The brace initialization used here generates errors on some
compilers. Use memset to make this more portable.

Cc: Sun peng Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5b7a85e28fab..9cdd52edfc3d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5982,7 +5982,9 @@ dm_determine_update_type_for_commit(struct dc *dc,
}
 
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
-   struct dc_stream_update stream_update = { 0 };
+   struct dc_stream_update stream_update;
+
+   memset(_update, 0, sizeof(stream_update));
 
new_dm_crtc_state = to_dm_crtc_state(new_crtc_state);
old_dm_crtc_state = to_dm_crtc_state(old_crtc_state);
-- 
2.17.1

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

[PATCH v2] drm/amd/display: Add debugfs entry for amdgpu_dm_visual_confirm

2019-03-22 Thread Nicholas Kazlauskas
[Why]
DC provides a few visual confirmation debug options that can be
dynamically changed at runtime to help debug surface programming issues
but we don't have any way to access it from userspace.

[How]
Add the amdgpu_dm_visual_confirm debugfs entry.
It accepts a string containing the DC visual confirm enum value using
the debugfs attribute helpers.

The debugfs_create_file_unsafe can be used instead of
debugfs_create_file as per the documentation.

v2: Use debugfs helpers for getting and setting the value (Christian)

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 39 ++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 1a9e3d3dfa38..1d5fc5ad3bee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -995,6 +995,35 @@ static const struct drm_info_list amdgpu_dm_debugfs_list[] 
= {
{"amdgpu_target_backlight_pwm", _backlight_read},
 };
 
+/*
+ * Sets the DC visual confirm debug option from the given string.
+ * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
+ */
+static int visual_confirm_set(void *data, u64 val)
+{
+   struct amdgpu_device *adev = data;
+
+   adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val;
+
+   return 0;
+}
+
+/*
+ * Reads the DC visual confirm debug option value into the given buffer.
+ * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm
+ */
+static int visual_confirm_get(void *data, u64 *val)
+{
+   struct amdgpu_device *adev = data;
+
+   *val = adev->dm.dc->debug.visual_confirm;
+
+   return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
+visual_confirm_set, "%llu\n");
+
 int dtn_debugfs_init(struct amdgpu_device *adev)
 {
static const struct file_operations dtn_log_fops = {
@@ -1020,5 +1049,13 @@ int dtn_debugfs_init(struct amdgpu_device *adev)
adev,
_log_fops);
 
-   return PTR_ERR_OR_ZERO(ent);
+   if (IS_ERR(ent))
+   return PTR_ERR(ent);
+
+   ent = debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root,
+adev, _confirm_fops);
+   if (IS_ERR(ent))
+   return PTR_ERR(ent);
+
+   return 0;
 }
-- 
2.17.1

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

[PATCH v2] drm/amd/display: Initialize stream_update with memset

2019-03-22 Thread Nicholas Kazlauskas
The brace initialization used here generates warnings on some
compilers. For example, on GCC 4.9:

[...] In function ‘dm_determine_update_type_for_commit’:
[...] error: missing braces around initializer [-Werror=missing-braces]
   struct dc_stream_update stream_update = { 0 };
  ^

Use memset to make this more portable.

v2: Specify the compiler / diagnostic in the commit message (Paul)

Cc: Sun peng Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5b7a85e28fab..9cdd52edfc3d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5982,7 +5982,9 @@ dm_determine_update_type_for_commit(struct dc *dc,
}
 
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
-   struct dc_stream_update stream_update = { 0 };
+   struct dc_stream_update stream_update;
+
+   memset(_update, 0, sizeof(stream_update));
 
new_dm_crtc_state = to_dm_crtc_state(new_crtc_state);
old_dm_crtc_state = to_dm_crtc_state(old_crtc_state);
-- 
2.17.1

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

Re: "ring gfx timeout" with Vega 64 on mesa 19.0.0-rc2 and kernel 5.0.0-rc6 (GPU reset still not works)

2019-02-12 Thread Nicholas Kazlauskas
The MAX_SCHEDULE_TIMEOUT is probably not a good idea on the wait in DM.

I wonder if we could just do shorter wait and skip the FB 
update/programming if it fails after some reasonable amount of time.

This would still allow recovery to happen at least even if the display 
isn't showing the right buffer.

Nicholas Kazlauskas

On 2/12/19 12:46 PM, Grodzovsky, Andrey wrote:
> I suspect the issue is that amdgpu_dm_do_flip is holding the BO reserved
> and then stack waiting for fences to signal in
> reservation_object_wait_timeout_rcu (which won't signal because there
> was a VM_FAULT). Then when we try to shutdown display block during reset
> recovery from drm_atomic_helper_suspend we also try to reserve the BO,
> probably from dm_plane_helper_cleanup_fb ending in deadlock.
> 
> To confirm i am attaching some printks around the BO reservation -
> please apply and rerun.
> 
> Also, probably a good idea to open FDO ticket on this instead of using
> amd-gfx.
> 
> Andrey
> 
> 
> On 2/12/19 10:49 AM, Mikhail Gavrilov wrote:
>> On Tue, 12 Feb 2019 at 20:23, Grodzovsky, Andrey
>>  wrote:
>>> It should recover you - so this looks like a bug. I noticed in one of
>>> the call traces this - drm_atomic_helper_suspend which points to system
>>> going into sleep mode, is it what happened, did it hang when system
>>> tried to sleep ?
>>>
>> It's weird because the computer was not enter in sleep mode. I am sure.
>> Steps for reproduce:
>> 1. Launch Shadow of The tomb Rider on Proton2. Wait some time until mouse 
>> stop respond
>> 3. Dump gfx, waves and all other dumps including dmesg
>>
>> And of course the power button (button which enter in sleep mode) was
>> not pressed.
>>
>> So the new dumps has any new useful info? Or they are pointless?
>> --
>> Best Regards,
>> Mike Gavrilov.
>>
>> ___
>> 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] drm/amd/display: Attach VRR properties for eDP connectors

2019-01-31 Thread Nicholas Kazlauskas
[Why]
eDP was missing in the checks for supported VRR connectors.

[How]
Attach the properties for eDP connectors too.

Cc: Leo Li 
Cc: Harry Wentland 
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202449
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index cdda68aba70e..4c7c34cae882 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4249,7 +4249,8 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
}
 
if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
-   connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+   connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+   connector_type == DRM_MODE_CONNECTOR_eDP) {
drm_connector_attach_vrr_capable_property(
>base);
drm_object_attach_property(>base.base,
-- 
2.17.1

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


[PATCH] drm/amd/display: Expose connector VRR range via debugfs

2019-01-24 Thread Nicholas Kazlauskas
[Why]
It's useful to know the min and max vrr range for IGT testing.

[How]
Expose the min and max vfreq for the connector via a debugfs file
on the connector, "vrr_range".

Example usage: cat /sys/kernel/debug/dri/0/DP-1/vrr_range

Cc: Harry Wentland 
Cc: Leo Li 
Signed-off-by: Nicholas Kazlauskas 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 22 ++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index cca3e16cda4f..4a55cde027cf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -671,6 +671,25 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct 
file *f, const char __us
return bytes_from_user;
 }
 
+/*
+ * Returns the min and max vrr vfreq through the connector's debugfs file.
+ * Example usage: cat /sys/kernel/debug/dri/0/DP-1/vrr_range
+ */
+static int vrr_range_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+
+   if (connector->status != connector_status_connected)
+   return -ENODEV;
+
+   seq_printf(m, "Min: %u\n", (unsigned int)aconnector->min_vfreq);
+   seq_printf(m, "Max: %u\n", (unsigned int)aconnector->max_vfreq);
+
+   return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(vrr_range);
+
 static const struct file_operations dp_link_settings_debugfs_fops = {
.owner = THIS_MODULE,
.read = dp_link_settings_read,
@@ -697,7 +716,8 @@ static const struct {
 } dp_debugfs_entries[] = {
{"link_settings", _link_settings_debugfs_fops},
{"phy_settings", _phy_settings_debugfs_fop},
-   {"test_pattern", _phy_test_pattern_fops}
+   {"test_pattern", _phy_test_pattern_fops},
+   {"vrr_range", _range_fops}
 };
 
 int connector_debugfs_init(struct amdgpu_dm_connector *connector)
-- 
2.17.1

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


[PATCH] drm/amd/display: Don't re-enable CRC when CONFIG_DEBUG_FS isn't defined

2019-02-04 Thread Nicholas Kazlauskas
[Why]
When CONFIG_DEBUG_FS isn't defined then amdgpu_dm_crtc_set_crc_source
is NULL. This causes a compilation error since it's being called
unconditionally.

[How]
Guard the call based on CONFIG_DEBUG_FS - CRC capture isn't supported
without this.

Cc: Leo Li 
Cc: Harry Wentland 
Fixes: 43a6a02eb355 ("drm/amd/display: Re-enable CRC capture following modeset")
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a2453900e15a..cacb8fe5a1ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5284,9 +5284,11 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
 
manage_dm_interrupts(adev, acrtc, true);
 
+#ifdef CONFIG_DEBUG_FS
/* The stream has changed so CRC capture needs to re-enabled. */
if (dm_new_crtc_state->crc_enabled)
amdgpu_dm_crtc_set_crc_source(crtc, "auto");
+#endif
}
 
/* update planes when needed per crtc*/
-- 
2.17.1

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


[PATCH] drm/amd/display: Add debugfs entry for amdgpu_dm_visual_confirm

2019-03-15 Thread Nicholas Kazlauskas
[Why]
DC provides a few visual confirmation debug options that can be
dynamically changed at runtime to help debug surface programming issues
but we don't have any way to access it from userspace.

[How]
Add the amdgpu_dm_visual_confirm debugfs entry.
It accepts a string containing the DC visual confirm enum value.

Cc: Leo Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 77 ++-
 1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 4a55cde027cf..1d6bfb84d7cf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -803,6 +803,65 @@ static ssize_t dtn_log_write(
return size;
 }
 
+/*
+ * Reads the DC visual confirm debug option value into the given buffer.
+ * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm
+ */
+static ssize_t visual_confirm_read(struct file *f, char __user *buf,
+  size_t size, loff_t *pos)
+{
+   struct amdgpu_device *adev = file_inode(f)->i_private;
+   struct dc *dc = adev->dm.dc;
+   size_t to_copy = 0;
+   int len;
+   char tmp[16];
+
+   if (!buf || !size)
+   return -EINVAL;
+
+   len = snprintf(tmp, sizeof(tmp), "%d\n", dc->debug.visual_confirm);
+   if (len < 0 || len >= sizeof(tmp))
+   return -EINVAL;
+
+   if (*pos >= len)
+   return 0;
+
+   to_copy = len - *pos;
+   if (to_copy > size)
+   return 0;
+
+   if (copy_to_user(buf, tmp + *pos, to_copy))
+   return -EFAULT;
+
+   *pos += to_copy;
+
+   return to_copy;
+}
+
+/*
+ * Sets the DC visual confirm debug option from the given string.
+ * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
+ */
+static ssize_t visual_confirm_write(struct file *f, const char __user *buf,
+   size_t size, loff_t *pos)
+{
+   struct amdgpu_device *adev = file_inode(f)->i_private;
+   struct dc *dc = adev->dm.dc;
+   int ret;
+   u16 val;
+
+   if (size == 0)
+   return 0;
+
+   ret = kstrtou16_from_user(buf, size, 0, );
+   if (ret)
+   return ret;
+
+   dc->debug.visual_confirm = val;
+
+   return size;
+}
+
 /*
  * Backlight at this moment.  Read only.
  * As written to display, taking ABM and backlight lut into account.
@@ -850,7 +909,12 @@ int dtn_debugfs_init(struct amdgpu_device *adev)
.write = dtn_log_write,
.llseek = default_llseek
};
-
+   static const struct file_operations visual_confirm_fops = {
+   .owner = THIS_MODULE,
+   .read = visual_confirm_read,
+   .write = visual_confirm_write,
+   .llseek = default_llseek
+   };
struct drm_minor *minor = adev->ddev->primary;
struct dentry *ent, *root = minor->debugfs_root;
int ret;
@@ -867,5 +931,14 @@ int dtn_debugfs_init(struct amdgpu_device *adev)
adev,
_log_fops);
 
-   return PTR_ERR_OR_ZERO(ent);
+   if (IS_ERR(ent))
+   return PTR_ERR(ent);
+
+   ent = debugfs_create_file("amdgpu_dm_visual_confirm", 0644, root, adev,
+ _confirm_fops);
+
+   if (IS_ERR(ent))
+   return PTR_ERR(ent);
+
+   return 0;
 }
-- 
2.17.1

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

[PATCH] drm/amd/display: Always allocate initial connector state state

2019-06-04 Thread Nicholas Kazlauskas
[Why]
Unlike our regular connectors, MST connectors don't start off with
an initial connector state. This causes a NULL pointer dereference to
occur when attaching the bpc property since it tries to modify the
connector state.

We need an initial connector state on the connector to avoid the crash.

[How]
Use our reset helper to allocate an initial state and reset the values
to their defaults. We were already doing this before, just not for
MST connectors.

Cc: Leo Li 
Cc: Roman Li 
Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++---
 1 file changed, 7 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 a698c8f272ed..4523ab100bc3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4743,6 +4743,13 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
 {
struct amdgpu_device *adev = dm->ddev->dev_private;
 
+   /*
+* Some of the properties below require access to state, like bpc.
+* Allocate some default initial connector state with our reset helper.
+*/
+   if (aconnector->base.funcs->reset)
+   aconnector->base.funcs->reset(>base);
+
aconnector->connector_id = link_index;
aconnector->dc_link = link;
aconnector->base.interlace_allowed = false;
@@ -4932,9 +4939,6 @@ static int amdgpu_dm_connector_init(struct 
amdgpu_display_manager *dm,
>base,
_dm_connector_helper_funcs);
 
-   if (aconnector->base.funcs->reset)
-   aconnector->base.funcs->reset(>base);
-
amdgpu_dm_connector_init_helper(
dm,
aconnector,
-- 
2.17.1

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

[PATCH 0/2] drm/amd/display: Add HDR output metadata support for amdgpu

2019-05-28 Thread Nicholas Kazlauskas
This patch series enables HDR output metadata support in amdgpu using the
DRM HDR interface merged in drm-misc-next. Enabled for DCE and DCN ASICs
over DP and HDMI.

It's limited to static HDR metadata support for now since that's all the
DRM interface supports. It requires a modeset for entering and exiting HDR
but the metadata can be changed without one.

Cc: Harry Wentland 

Nicholas Kazlauskas (2):
  drm/amd/display: Expose HDR output metadata for supported connectors
  drm/amd/display: Only force modesets when toggling HDR

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 155 +-
 1 file changed, 151 insertions(+), 4 deletions(-)

-- 
2.17.1

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

[PATCH 1/2] drm/amd/display: Expose HDR output metadata for supported connectors

2019-05-28 Thread Nicholas Kazlauskas
[Why]
For userspace to send static HDR metadata to the display we need to
attach the property on the connector and send it to DC.

[How]
The property is attached to HDMI and DP connectors. Since the metadata
isn't actually available when creating the connector this isn't a
property we can dynamically support based on the extension block
being available or not.

When the HDR metadata is changed a modeset will be forced for now.
We need to switch from 8bpc to 10bpc in most cases anyway, and we want
to fully exit HDR mode when userspace gives us a NULL metadata, so this
isn't completely unnecessary.

The requirement can later be reduced to just entering and exiting HDR
or switching max bpc.

Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 125 ++
 1 file changed, 125 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 995f9df66142..eb31acca7ed6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3871,6 +3871,121 @@ enum drm_mode_status 
amdgpu_dm_connector_mode_valid(struct drm_connector *connec
return result;
 }
 
+static int fill_hdr_info_packet(const struct drm_connector_state *state,
+   struct dc_info_packet *out)
+{
+   struct hdmi_drm_infoframe frame;
+   unsigned char buf[30]; /* 26 + 4 */
+   ssize_t len;
+   int ret, i;
+
+   memset(out, 0, sizeof(*out));
+
+   if (!state->hdr_output_metadata)
+   return 0;
+
+   ret = drm_hdmi_infoframe_set_hdr_metadata(, state);
+   if (ret)
+   return ret;
+
+   len = hdmi_drm_infoframe_pack_only(, buf, sizeof(buf));
+   if (len < 0)
+   return (int)len;
+
+   /* Static metadata is a fixed 26 bytes + 4 byte header. */
+   if (len != 30)
+   return -EINVAL;
+
+   /* Prepare the infopacket for DC. */
+   switch (state->connector->connector_type) {
+   case DRM_MODE_CONNECTOR_HDMIA:
+   out->hb0 = 0x87; /* type */
+   out->hb1 = 0x01; /* version */
+   out->hb2 = 0x1A; /* length */
+   out->sb[0] = buf[3]; /* checksum */
+   i = 1;
+   break;
+
+   case DRM_MODE_CONNECTOR_DisplayPort:
+   case DRM_MODE_CONNECTOR_eDP:
+   out->hb0 = 0x00; /* sdp id, zero */
+   out->hb1 = 0x87; /* type */
+   out->hb2 = 0x1D; /* payload len - 1 */
+   out->hb3 = (0x13 << 2); /* sdp version */
+   out->sb[0] = 0x01; /* version */
+   out->sb[1] = 0x1A; /* length */
+   i = 2;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
+   memcpy(>sb[i], [4], 26);
+   out->valid = true;
+
+   print_hex_dump(KERN_DEBUG, "HDR SB:", DUMP_PREFIX_NONE, 16, 1, out->sb,
+  sizeof(out->sb), false);
+
+   return 0;
+}
+
+static bool
+is_hdr_metadata_different(const struct drm_connector_state *old_state,
+ const struct drm_connector_state *new_state)
+{
+   struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
+   struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
+
+   if (old_blob != new_blob) {
+   if (old_blob && new_blob &&
+   old_blob->length == new_blob->length)
+   return memcmp(old_blob->data, new_blob->data,
+ old_blob->length);
+
+   return true;
+   }
+
+   return false;
+}
+
+static int
+amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
+struct drm_connector_state *new_con_state)
+{
+   struct drm_atomic_state *state = new_con_state->state;
+   struct drm_connector_state *old_con_state =
+   drm_atomic_get_old_connector_state(state, conn);
+   struct drm_crtc *crtc = new_con_state->crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int ret;
+
+   if (!crtc)
+   return 0;
+
+   if (is_hdr_metadata_different(old_con_state, new_con_state)) {
+   struct dc_info_packet hdr_infopacket;
+
+   ret = fill_hdr_info_packet(new_con_state, _infopacket);
+   if (ret)
+   return ret;
+
+   new_crtc_state = drm_atomic_get_crtc_state(state, crtc);
+   if (IS_ERR(new_crtc_state))
+   return PTR_ERR(new_crtc_state);
+
+   /*
+* DC considers the stream backends changed if the
+* static metadata changes. Forcing the modeset also
+* gives a simple way for userspace to switch fr

[PATCH 2/2] drm/amd/display: Only force modesets when toggling HDR

2019-05-28 Thread Nicholas Kazlauskas
[Why]
We can issue HDR static metadata as part of stream updates for
non-modesets as long as we force a modeset when entering or exiting HDR.

This avoids unnecessary blanking for simple metadata updates.

[How]
When changing scaling and abm for the stream also check if HDR has
changed and send the stream update. This will only happen in non-modeset
cases.

Cc: Harry Wentland 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 +++
 1 file changed, 28 insertions(+), 6 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 eb31acca7ed6..443b13ec268d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3978,9 +3978,16 @@ amdgpu_dm_connector_atomic_check(struct drm_connector 
*conn,
 * DC considers the stream backends changed if the
 * static metadata changes. Forcing the modeset also
 * gives a simple way for userspace to switch from
-* 8bpc to 10bpc when setting the metadata.
+* 8bpc to 10bpc when setting the metadata to enter
+* or exit HDR.
+*
+* Changing the static metadata after it's been
+* set is permissible, however. So only force a
+* modeset if we're entering or exiting HDR.
 */
-   new_crtc_state->mode_changed = true;
+   new_crtc_state->mode_changed =
+   !old_con_state->hdr_output_metadata ||
+   !new_con_state->hdr_output_metadata;
}
 
return 0;
@@ -5881,7 +5888,9 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
struct amdgpu_crtc *acrtc = 
to_amdgpu_crtc(dm_new_con_state->base.crtc);
struct dc_surface_update dummy_updates[MAX_SURFACES];
struct dc_stream_update stream_update;
+   struct dc_info_packet hdr_packet;
struct dc_stream_status *status = NULL;
+   bool abm_changed, hdr_changed, scaling_changed;
 
memset(_updates, 0, sizeof(dummy_updates));
memset(_update, 0, sizeof(stream_update));
@@ -5898,11 +5907,19 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 
-   if (!is_scaling_state_different(dm_new_con_state, 
dm_old_con_state) &&
-   (dm_new_crtc_state->abm_level == 
dm_old_crtc_state->abm_level))
+   scaling_changed = is_scaling_state_different(dm_new_con_state,
+dm_old_con_state);
+
+   abm_changed = dm_new_crtc_state->abm_level !=
+ dm_old_crtc_state->abm_level;
+
+   hdr_changed =
+   is_hdr_metadata_different(old_con_state, new_con_state);
+
+   if (!scaling_changed && !abm_changed && !hdr_changed)
continue;
 
-   if (is_scaling_state_different(dm_new_con_state, 
dm_old_con_state)) {
+   if (scaling_changed) {

update_stream_scaling_settings(_new_con_state->base.crtc->mode,
dm_new_con_state, (struct 
dc_stream_state *)dm_new_crtc_state->stream);
 
@@ -5910,12 +5927,17 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
stream_update.dst = dm_new_crtc_state->stream->dst;
}
 
-   if (dm_new_crtc_state->abm_level != 
dm_old_crtc_state->abm_level) {
+   if (abm_changed) {
dm_new_crtc_state->stream->abm_level = 
dm_new_crtc_state->abm_level;
 
stream_update.abm_level = _new_crtc_state->abm_level;
}
 
+   if (hdr_changed) {
+   fill_hdr_info_packet(new_con_state, _packet);
+   stream_update.hdr_static_metadata = _packet;
+   }
+
status = dc_stream_get_status(dm_new_crtc_state->stream);
WARN_ON(!status);
WARN_ON(!status->plane_count);
-- 
2.17.1

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

[PATCH] drm/amd/display: Add back missing hw translate init for DCN1_01

2019-05-31 Thread Nicholas Kazlauskas
[Why]
DCN_VERSION_1_01 is no longer handled in the dal_hw_translate_init
switch since it was inadvertently dropped in the patch that removed the
unnecessary DCN1_01 guards.

This caused numerous regressions on DCN1_01 when loading the driver.

[How]
Add it back.

Cc: Harry Wentland 
Fixes: 97df424fe7a7 ("drm/amd/display: Drop DCN1_01 guards")
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c 
b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
index 77615146b96e..1f9833dc8cfe 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
@@ -81,6 +81,7 @@ bool dal_hw_translate_init(
return true;
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
case DCN_VERSION_1_0:
+   case DCN_VERSION_1_01:
dal_hw_translate_dcn10_init(translate);
return true;
 #endif
-- 
2.17.1

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

  1   2   >