[5/6] kms/nv50: detect HDMI max MHz correctly

Submitted by Karol Herbst on July 20, 2018, 3:17 p.m.

Details

Message ID 20180720151729.30291-6-kherbst@redhat.com
State New
Headers show
Series "improve feature detection" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Karol Herbst July 20, 2018, 3:17 p.m.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 drm/nouveau/dispnv50/disp.c     | 5 +++++
 drm/nouveau/nouveau_connector.c | 5 +++++
 drm/nouveau/nouveau_encoder.h   | 4 ++++
 3 files changed, 14 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drm/nouveau/dispnv50/disp.c b/drm/nouveau/dispnv50/disp.c
index 6f41a6a0..3a960664 100644
--- a/drm/nouveau/dispnv50/disp.c
+++ b/drm/nouveau/dispnv50/disp.c
@@ -1433,7 +1433,12 @@  nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe,
 	case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break;
 	case DCB_OUTPUT_DP:
 		nv_encoder->dp.no_interlace = caps->dp[or].no_interlace;
+		type = DRM_MODE_ENCODER_TMDS;
+		break;
 	case DCB_OUTPUT_TMDS:
+		nv_encoder->tmds.max_mhz = caps->tmds[or].max_mhz;
+		type = DRM_MODE_ENCODER_TMDS;
+		break;
 	default:
 		type = DRM_MODE_ENCODER_TMDS;
 		break;
diff --git a/drm/nouveau/nouveau_connector.c b/drm/nouveau/nouveau_connector.c
index 074e6d52..a955f225 100644
--- a/drm/nouveau/nouveau_connector.c
+++ b/drm/nouveau/nouveau_connector.c
@@ -980,9 +980,14 @@  static unsigned
 get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
 {
 	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
 	struct nouveau_drm *drm = nouveau_drm(connector->dev);
 	struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
 
+	/* cap to 297MHz until we figure out HDMI 2.0 */
+	if (nv_encoder->tmds.max_mhz)
+		return nv_encoder->tmds.max_mhz * 1000;
+
 	if (hdmi) {
 		if (nouveau_hdmimhz > 0)
 			return nouveau_hdmimhz * 1000;
diff --git a/drm/nouveau/nouveau_encoder.h b/drm/nouveau/nouveau_encoder.h
index f74af5ce..fbef9dc0 100644
--- a/drm/nouveau/nouveau_encoder.h
+++ b/drm/nouveau/nouveau_encoder.h
@@ -65,6 +65,10 @@  struct nouveau_encoder {
 			int link_bw;
 			bool no_interlace;
 		} dp;
+
+		struct {
+			uint16_t max_mhz;
+		} tmds;
 	};
 
 	void (*enc_save)(struct drm_encoder *encoder);

Comments

This removes user control to force a hdmimhz. Given the vast variety
of hardware and display configurations out there, I don't see how a
patch like this won't blow up in our faces.

I'm not saying we shouldn't do it -- we should attempt to respect the
various maximums in the vbios, but until we get a solid handle on
things, we should allow more user-configurability, not less, for the
case where we get it wrong.

2018-07-20 11:17 GMT-04:00 Karol Herbst <kherbst@redhat.com>:
> Signed-off-by: Karol Herbst <kherbst@redhat.com>
> ---
>  drm/nouveau/dispnv50/disp.c     | 5 +++++
>  drm/nouveau/nouveau_connector.c | 5 +++++
>  drm/nouveau/nouveau_encoder.h   | 4 ++++
>  3 files changed, 14 insertions(+)
>
> diff --git a/drm/nouveau/dispnv50/disp.c b/drm/nouveau/dispnv50/disp.c
> index 6f41a6a0..3a960664 100644
> --- a/drm/nouveau/dispnv50/disp.c
> +++ b/drm/nouveau/dispnv50/disp.c
> @@ -1433,7 +1433,12 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe,
>         case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break;
>         case DCB_OUTPUT_DP:
>                 nv_encoder->dp.no_interlace = caps->dp[or].no_interlace;
> +               type = DRM_MODE_ENCODER_TMDS;
> +               break;
>         case DCB_OUTPUT_TMDS:
> +               nv_encoder->tmds.max_mhz = caps->tmds[or].max_mhz;
> +               type = DRM_MODE_ENCODER_TMDS;
> +               break;
>         default:
>                 type = DRM_MODE_ENCODER_TMDS;
>                 break;
> diff --git a/drm/nouveau/nouveau_connector.c b/drm/nouveau/nouveau_connector.c
> index 074e6d52..a955f225 100644
> --- a/drm/nouveau/nouveau_connector.c
> +++ b/drm/nouveau/nouveau_connector.c
> @@ -980,9 +980,14 @@ static unsigned
>  get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
>  {
>         struct nouveau_connector *nv_connector = nouveau_connector(connector);
> +       struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
>         struct nouveau_drm *drm = nouveau_drm(connector->dev);
>         struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
>
> +       /* cap to 297MHz until we figure out HDMI 2.0 */
> +       if (nv_encoder->tmds.max_mhz)
> +               return nv_encoder->tmds.max_mhz * 1000;
> +
>         if (hdmi) {
>                 if (nouveau_hdmimhz > 0)
>                         return nouveau_hdmimhz * 1000;
> diff --git a/drm/nouveau/nouveau_encoder.h b/drm/nouveau/nouveau_encoder.h
> index f74af5ce..fbef9dc0 100644
> --- a/drm/nouveau/nouveau_encoder.h
> +++ b/drm/nouveau/nouveau_encoder.h
> @@ -65,6 +65,10 @@ struct nouveau_encoder {
>                         int link_bw;
>                         bool no_interlace;
>                 } dp;
> +
> +               struct {
> +                       uint16_t max_mhz;
> +               } tmds;
>         };
>
>         void (*enc_save)(struct drm_encoder *encoder);
> --
> 2.17.1
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/nouveau
On Fri, Jul 20, 2018 at 5:58 PM, Ilia Mirkin <imirkin@alum.mit.edu> wrote:
> This removes user control to force a hdmimhz. Given the vast variety
> of hardware and display configurations out there, I don't see how a
> patch like this won't blow up in our faces.
>
> I'm not saying we shouldn't do it -- we should attempt to respect the
> various maximums in the vbios, but until we get a solid handle on
> things, we should allow more user-configurability, not less, for the
> case where we get it wrong.
>

yeah, probably a good idea. I also removed the cap to 297 without
removing the comment. Shame on me.

> 2018-07-20 11:17 GMT-04:00 Karol Herbst <kherbst@redhat.com>:
>> Signed-off-by: Karol Herbst <kherbst@redhat.com>
>> ---
>>  drm/nouveau/dispnv50/disp.c     | 5 +++++
>>  drm/nouveau/nouveau_connector.c | 5 +++++
>>  drm/nouveau/nouveau_encoder.h   | 4 ++++
>>  3 files changed, 14 insertions(+)
>>
>> diff --git a/drm/nouveau/dispnv50/disp.c b/drm/nouveau/dispnv50/disp.c
>> index 6f41a6a0..3a960664 100644
>> --- a/drm/nouveau/dispnv50/disp.c
>> +++ b/drm/nouveau/dispnv50/disp.c
>> @@ -1433,7 +1433,12 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe,
>>         case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break;
>>         case DCB_OUTPUT_DP:
>>                 nv_encoder->dp.no_interlace = caps->dp[or].no_interlace;
>> +               type = DRM_MODE_ENCODER_TMDS;
>> +               break;
>>         case DCB_OUTPUT_TMDS:
>> +               nv_encoder->tmds.max_mhz = caps->tmds[or].max_mhz;
>> +               type = DRM_MODE_ENCODER_TMDS;
>> +               break;
>>         default:
>>                 type = DRM_MODE_ENCODER_TMDS;
>>                 break;
>> diff --git a/drm/nouveau/nouveau_connector.c b/drm/nouveau/nouveau_connector.c
>> index 074e6d52..a955f225 100644
>> --- a/drm/nouveau/nouveau_connector.c
>> +++ b/drm/nouveau/nouveau_connector.c
>> @@ -980,9 +980,14 @@ static unsigned
>>  get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
>>  {
>>         struct nouveau_connector *nv_connector = nouveau_connector(connector);
>> +       struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
>>         struct nouveau_drm *drm = nouveau_drm(connector->dev);
>>         struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
>>
>> +       /* cap to 297MHz until we figure out HDMI 2.0 */
>> +       if (nv_encoder->tmds.max_mhz)
>> +               return nv_encoder->tmds.max_mhz * 1000;
>> +
>>         if (hdmi) {
>>                 if (nouveau_hdmimhz > 0)
>>                         return nouveau_hdmimhz * 1000;
>> diff --git a/drm/nouveau/nouveau_encoder.h b/drm/nouveau/nouveau_encoder.h
>> index f74af5ce..fbef9dc0 100644
>> --- a/drm/nouveau/nouveau_encoder.h
>> +++ b/drm/nouveau/nouveau_encoder.h
>> @@ -65,6 +65,10 @@ struct nouveau_encoder {
>>                         int link_bw;
>>                         bool no_interlace;
>>                 } dp;
>> +
>> +               struct {
>> +                       uint16_t max_mhz;
>> +               } tmds;
>>         };
>>
>>         void (*enc_save)(struct drm_encoder *encoder);
>> --
>> 2.17.1
>>
>> _______________________________________________
>> Nouveau mailing list
>> Nouveau@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/nouveau