From: Jani Nikula <jani.nikula@intel.com>
To: Matt Roper <matthew.d.roper@intel.com>, intel-gfx@lists.freedesktop.org
Subject: Re: [CI v5 2/2] drm/i915/vbt: Handle generic DTD block
Date: Mon, 18 Nov 2019 13:38:09 +0200 [thread overview]
Message-ID: <87lfsdza72.fsf@intel.com> (raw)
In-Reply-To: <20191115165132.9472-3-matthew.d.roper@intel.com>
On Fri, 15 Nov 2019, Matt Roper <matthew.d.roper@intel.com> wrote:
> VBT revision 229 adds a new "Generic DTD" block 58 and deprecates the
> old LFP panel mode data in block 42. Let's start parsing this block to
> fill in the panel fixed mode on devices with a >=229 VBT.
>
> v2:
> * Update according to the recent updates:
> - DTD size is now 16 bits instead of 24
> - polarity is now just a single bit for hsync and vsync and is
> properly documented
> * Minor checkpatch fix
>
> v3:
> * Now that panel options are parsed separately from the previous patch,
> move generic DTD parsing into a function parallel to
> parse_lfp_panel_dtd. We'll still fall back to looking at the legacy
> LVDS timing block if the generic DTD fails. (Jani)
> * Don't forget to actually set lfp_lvds_vbt_mode! (Jani)
> * Drop "bdb_" prefix from dtd entry structure. (Jani)
> * Follow C99 standard for structure's flexible array member. (Jani)
>
> v4:
> * Add "positive" to polarity field names for clarity. (Jani)
> * Move VBT version check and fallback to legacy DTD parsing logic to a
> helper to keep top-level VBT parsing uncluttered. (Jani)
> * Restructure reserved bit packing at end of generic_dtd_entry from
> "u32 rsvd:24" to "u8 rsvd[3]" to prevent copy/paste mistakes in the
> future. (Jani)
Thanks, looks nice.
BR,
Jani.
>
> Bspec: 54751
> Bspec: 20148
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_bios.c | 96 ++++++++++++++++++-
> drivers/gpu/drm/i915/display/intel_vbt_defs.h | 31 ++++++
> 2 files changed, 125 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
> index d13ce0b7db8b..f6a9a5ccb556 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -296,7 +296,7 @@ parse_lfp_panel_dtd(struct drm_i915_private *dev_priv,
>
> dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
>
> - DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
> + DRM_DEBUG_KMS("Found panel mode in BIOS VBT legacy lfp table:\n");
> drm_mode_debug_printmodeline(panel_fixed_mode);
>
> fp_timing = get_lvds_fp_timing(bdb, lvds_lfp_data,
> @@ -313,6 +313,98 @@ parse_lfp_panel_dtd(struct drm_i915_private *dev_priv,
> }
> }
>
> +static void
> +parse_generic_dtd(struct drm_i915_private *dev_priv,
> + const struct bdb_header *bdb)
> +{
> + const struct bdb_generic_dtd *generic_dtd;
> + const struct generic_dtd_entry *dtd;
> + struct drm_display_mode *panel_fixed_mode;
> + int num_dtd;
> +
> + generic_dtd = find_section(bdb, BDB_GENERIC_DTD);
> + if (!generic_dtd)
> + return;
> +
> + if (generic_dtd->gdtd_size < sizeof(struct generic_dtd_entry)) {
> + DRM_ERROR("GDTD size %u is too small.\n",
> + generic_dtd->gdtd_size);
> + return;
> + } else if (generic_dtd->gdtd_size !=
> + sizeof(struct generic_dtd_entry)) {
> + DRM_ERROR("Unexpected GDTD size %u\n", generic_dtd->gdtd_size);
> + /* DTD has unknown fields, but keep going */
> + }
> +
> + num_dtd = (get_blocksize(generic_dtd) -
> + sizeof(struct bdb_generic_dtd)) / generic_dtd->gdtd_size;
> + if (dev_priv->vbt.panel_type > num_dtd) {
> + DRM_ERROR("Panel type %d not found in table of %d DTD's\n",
> + dev_priv->vbt.panel_type, num_dtd);
> + return;
> + }
> +
> + dtd = &generic_dtd->dtd[dev_priv->vbt.panel_type];
> +
> + panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
> + if (!panel_fixed_mode)
> + return;
> +
> + panel_fixed_mode->hdisplay = dtd->hactive;
> + panel_fixed_mode->hsync_start =
> + panel_fixed_mode->hdisplay + dtd->hfront_porch;
> + panel_fixed_mode->hsync_end =
> + panel_fixed_mode->hsync_start + dtd->hsync;
> + panel_fixed_mode->htotal = panel_fixed_mode->hsync_end;
> +
> + panel_fixed_mode->vdisplay = dtd->vactive;
> + panel_fixed_mode->vsync_start =
> + panel_fixed_mode->vdisplay + dtd->vfront_porch;
> + panel_fixed_mode->vsync_end =
> + panel_fixed_mode->vsync_start + dtd->vsync;
> + panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end;
> +
> + panel_fixed_mode->clock = dtd->pixel_clock;
> + panel_fixed_mode->width_mm = dtd->width_mm;
> + panel_fixed_mode->height_mm = dtd->height_mm;
> +
> + panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
> + drm_mode_set_name(panel_fixed_mode);
> +
> + if (dtd->hsync_positive_polarity)
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
> + else
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
> +
> + if (dtd->vsync_positive_polarity)
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
> + else
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
> +
> + DRM_DEBUG_KMS("Found panel mode in BIOS VBT generic dtd table:\n");
> + drm_mode_debug_printmodeline(panel_fixed_mode);
> +
> + dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
> +}
> +
> +static void
> +parse_panel_dtd(struct drm_i915_private *dev_priv,
> + const struct bdb_header *bdb)
> +{
> + /*
> + * Older VBTs provided provided DTD information for internal displays
> + * through the "LFP panel DTD" block (42). As of VBT revision 229,
> + * that block is now deprecated and DTD information should be provided
> + * via a newer "generic DTD" block (58). Just to be safe, we'll
> + * try the new generic DTD block first on VBT >= 229, but still fall
> + * back to trying the old LFP block if that fails.
> + */
> + if (bdb->version >= 229)
> + parse_generic_dtd(dev_priv, bdb);
> + if (!dev_priv->vbt.lfp_lvds_vbt_mode)
> + parse_lfp_panel_dtd(dev_priv, bdb);
> +}
> +
> static void
> parse_lfp_backlight(struct drm_i915_private *dev_priv,
> const struct bdb_header *bdb)
> @@ -1877,7 +1969,7 @@ void intel_bios_init(struct drm_i915_private *dev_priv)
> parse_general_features(dev_priv, bdb);
> parse_general_definitions(dev_priv, bdb);
> parse_panel_options(dev_priv, bdb);
> - parse_lfp_panel_dtd(dev_priv, bdb);
> + parse_panel_dtd(dev_priv, bdb);
> parse_lfp_backlight(dev_priv, bdb);
> parse_sdvo_panel_data(dev_priv, bdb);
> parse_driver_features(dev_priv, bdb);
> diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> index 69a7cb1fa121..f0338da3a82a 100644
> --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> @@ -115,6 +115,7 @@ enum bdb_block_id {
> BDB_MIPI_CONFIG = 52,
> BDB_MIPI_SEQUENCE = 53,
> BDB_COMPRESSION_PARAMETERS = 56,
> + BDB_GENERIC_DTD = 58,
> BDB_SKIP = 254, /* VBIOS private block, ignore */
> };
>
> @@ -863,4 +864,34 @@ struct bdb_compression_parameters {
> struct dsc_compression_parameters_entry data[16];
> } __packed;
>
> +/*
> + * Block 58 - Generic DTD Block
> + */
> +
> +struct generic_dtd_entry {
> + u32 pixel_clock;
> + u16 hactive;
> + u16 hblank;
> + u16 hfront_porch;
> + u16 hsync;
> + u16 vactive;
> + u16 vblank;
> + u16 vfront_porch;
> + u16 vsync;
> + u16 width_mm;
> + u16 height_mm;
> +
> + /* Flags */
> + u8 rsvd_flags:6;
> + u8 vsync_positive_polarity:1;
> + u8 hsync_positive_polarity:1;
> +
> + u8 rsvd[3];
> +} __packed;
> +
> +struct bdb_generic_dtd {
> + u16 gdtd_size;
> + struct generic_dtd_entry dtd[]; /* up to 24 DTD's */
> +} __packed;
> +
> #endif /* _INTEL_VBT_DEFS_H_ */
--
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
WARNING: multiple messages have this Message-ID (diff)
From: Jani Nikula <jani.nikula@intel.com>
To: Matt Roper <matthew.d.roper@intel.com>, intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [CI v5 2/2] drm/i915/vbt: Handle generic DTD block
Date: Mon, 18 Nov 2019 13:38:09 +0200 [thread overview]
Message-ID: <87lfsdza72.fsf@intel.com> (raw)
Message-ID: <20191118113809.IQgx9zDYyHGJTYO1PjGPP3wW56unoBfipzaK1pVFj3Q@z> (raw)
In-Reply-To: <20191115165132.9472-3-matthew.d.roper@intel.com>
On Fri, 15 Nov 2019, Matt Roper <matthew.d.roper@intel.com> wrote:
> VBT revision 229 adds a new "Generic DTD" block 58 and deprecates the
> old LFP panel mode data in block 42. Let's start parsing this block to
> fill in the panel fixed mode on devices with a >=229 VBT.
>
> v2:
> * Update according to the recent updates:
> - DTD size is now 16 bits instead of 24
> - polarity is now just a single bit for hsync and vsync and is
> properly documented
> * Minor checkpatch fix
>
> v3:
> * Now that panel options are parsed separately from the previous patch,
> move generic DTD parsing into a function parallel to
> parse_lfp_panel_dtd. We'll still fall back to looking at the legacy
> LVDS timing block if the generic DTD fails. (Jani)
> * Don't forget to actually set lfp_lvds_vbt_mode! (Jani)
> * Drop "bdb_" prefix from dtd entry structure. (Jani)
> * Follow C99 standard for structure's flexible array member. (Jani)
>
> v4:
> * Add "positive" to polarity field names for clarity. (Jani)
> * Move VBT version check and fallback to legacy DTD parsing logic to a
> helper to keep top-level VBT parsing uncluttered. (Jani)
> * Restructure reserved bit packing at end of generic_dtd_entry from
> "u32 rsvd:24" to "u8 rsvd[3]" to prevent copy/paste mistakes in the
> future. (Jani)
Thanks, looks nice.
BR,
Jani.
>
> Bspec: 54751
> Bspec: 20148
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_bios.c | 96 ++++++++++++++++++-
> drivers/gpu/drm/i915/display/intel_vbt_defs.h | 31 ++++++
> 2 files changed, 125 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
> index d13ce0b7db8b..f6a9a5ccb556 100644
> --- a/drivers/gpu/drm/i915/display/intel_bios.c
> +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> @@ -296,7 +296,7 @@ parse_lfp_panel_dtd(struct drm_i915_private *dev_priv,
>
> dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
>
> - DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
> + DRM_DEBUG_KMS("Found panel mode in BIOS VBT legacy lfp table:\n");
> drm_mode_debug_printmodeline(panel_fixed_mode);
>
> fp_timing = get_lvds_fp_timing(bdb, lvds_lfp_data,
> @@ -313,6 +313,98 @@ parse_lfp_panel_dtd(struct drm_i915_private *dev_priv,
> }
> }
>
> +static void
> +parse_generic_dtd(struct drm_i915_private *dev_priv,
> + const struct bdb_header *bdb)
> +{
> + const struct bdb_generic_dtd *generic_dtd;
> + const struct generic_dtd_entry *dtd;
> + struct drm_display_mode *panel_fixed_mode;
> + int num_dtd;
> +
> + generic_dtd = find_section(bdb, BDB_GENERIC_DTD);
> + if (!generic_dtd)
> + return;
> +
> + if (generic_dtd->gdtd_size < sizeof(struct generic_dtd_entry)) {
> + DRM_ERROR("GDTD size %u is too small.\n",
> + generic_dtd->gdtd_size);
> + return;
> + } else if (generic_dtd->gdtd_size !=
> + sizeof(struct generic_dtd_entry)) {
> + DRM_ERROR("Unexpected GDTD size %u\n", generic_dtd->gdtd_size);
> + /* DTD has unknown fields, but keep going */
> + }
> +
> + num_dtd = (get_blocksize(generic_dtd) -
> + sizeof(struct bdb_generic_dtd)) / generic_dtd->gdtd_size;
> + if (dev_priv->vbt.panel_type > num_dtd) {
> + DRM_ERROR("Panel type %d not found in table of %d DTD's\n",
> + dev_priv->vbt.panel_type, num_dtd);
> + return;
> + }
> +
> + dtd = &generic_dtd->dtd[dev_priv->vbt.panel_type];
> +
> + panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
> + if (!panel_fixed_mode)
> + return;
> +
> + panel_fixed_mode->hdisplay = dtd->hactive;
> + panel_fixed_mode->hsync_start =
> + panel_fixed_mode->hdisplay + dtd->hfront_porch;
> + panel_fixed_mode->hsync_end =
> + panel_fixed_mode->hsync_start + dtd->hsync;
> + panel_fixed_mode->htotal = panel_fixed_mode->hsync_end;
> +
> + panel_fixed_mode->vdisplay = dtd->vactive;
> + panel_fixed_mode->vsync_start =
> + panel_fixed_mode->vdisplay + dtd->vfront_porch;
> + panel_fixed_mode->vsync_end =
> + panel_fixed_mode->vsync_start + dtd->vsync;
> + panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end;
> +
> + panel_fixed_mode->clock = dtd->pixel_clock;
> + panel_fixed_mode->width_mm = dtd->width_mm;
> + panel_fixed_mode->height_mm = dtd->height_mm;
> +
> + panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
> + drm_mode_set_name(panel_fixed_mode);
> +
> + if (dtd->hsync_positive_polarity)
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
> + else
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
> +
> + if (dtd->vsync_positive_polarity)
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
> + else
> + panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
> +
> + DRM_DEBUG_KMS("Found panel mode in BIOS VBT generic dtd table:\n");
> + drm_mode_debug_printmodeline(panel_fixed_mode);
> +
> + dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
> +}
> +
> +static void
> +parse_panel_dtd(struct drm_i915_private *dev_priv,
> + const struct bdb_header *bdb)
> +{
> + /*
> + * Older VBTs provided provided DTD information for internal displays
> + * through the "LFP panel DTD" block (42). As of VBT revision 229,
> + * that block is now deprecated and DTD information should be provided
> + * via a newer "generic DTD" block (58). Just to be safe, we'll
> + * try the new generic DTD block first on VBT >= 229, but still fall
> + * back to trying the old LFP block if that fails.
> + */
> + if (bdb->version >= 229)
> + parse_generic_dtd(dev_priv, bdb);
> + if (!dev_priv->vbt.lfp_lvds_vbt_mode)
> + parse_lfp_panel_dtd(dev_priv, bdb);
> +}
> +
> static void
> parse_lfp_backlight(struct drm_i915_private *dev_priv,
> const struct bdb_header *bdb)
> @@ -1877,7 +1969,7 @@ void intel_bios_init(struct drm_i915_private *dev_priv)
> parse_general_features(dev_priv, bdb);
> parse_general_definitions(dev_priv, bdb);
> parse_panel_options(dev_priv, bdb);
> - parse_lfp_panel_dtd(dev_priv, bdb);
> + parse_panel_dtd(dev_priv, bdb);
> parse_lfp_backlight(dev_priv, bdb);
> parse_sdvo_panel_data(dev_priv, bdb);
> parse_driver_features(dev_priv, bdb);
> diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> index 69a7cb1fa121..f0338da3a82a 100644
> --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> @@ -115,6 +115,7 @@ enum bdb_block_id {
> BDB_MIPI_CONFIG = 52,
> BDB_MIPI_SEQUENCE = 53,
> BDB_COMPRESSION_PARAMETERS = 56,
> + BDB_GENERIC_DTD = 58,
> BDB_SKIP = 254, /* VBIOS private block, ignore */
> };
>
> @@ -863,4 +864,34 @@ struct bdb_compression_parameters {
> struct dsc_compression_parameters_entry data[16];
> } __packed;
>
> +/*
> + * Block 58 - Generic DTD Block
> + */
> +
> +struct generic_dtd_entry {
> + u32 pixel_clock;
> + u16 hactive;
> + u16 hblank;
> + u16 hfront_porch;
> + u16 hsync;
> + u16 vactive;
> + u16 vblank;
> + u16 vfront_porch;
> + u16 vsync;
> + u16 width_mm;
> + u16 height_mm;
> +
> + /* Flags */
> + u8 rsvd_flags:6;
> + u8 vsync_positive_polarity:1;
> + u8 hsync_positive_polarity:1;
> +
> + u8 rsvd[3];
> +} __packed;
> +
> +struct bdb_generic_dtd {
> + u16 gdtd_size;
> + struct generic_dtd_entry dtd[]; /* up to 24 DTD's */
> +} __packed;
> +
> #endif /* _INTEL_VBT_DEFS_H_ */
--
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2019-11-18 11:38 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-15 16:51 [CI v5 0/2] VBT "generic DTD" block Matt Roper
2019-11-15 16:51 ` [Intel-gfx] " Matt Roper
2019-11-15 16:51 ` [CI v5 1/2] drm/i915/vbt: Parse panel options separately from timing data Matt Roper
2019-11-15 16:51 ` [Intel-gfx] " Matt Roper
2019-11-15 16:51 ` [CI v5 2/2] drm/i915/vbt: Handle generic DTD block Matt Roper
2019-11-15 16:51 ` [Intel-gfx] " Matt Roper
2019-11-18 11:38 ` Jani Nikula [this message]
2019-11-18 11:38 ` Jani Nikula
2019-11-15 21:12 ` ✗ Fi.CI.BAT: failure for VBT "generic DTD" block (rev2) Patchwork
2019-11-15 21:12 ` [Intel-gfx] " Patchwork
2019-11-15 21:39 ` Matt Roper
2019-11-15 21:39 ` [Intel-gfx] " Matt Roper
2019-11-16 1:48 ` ✓ Fi.CI.BAT: success for VBT "generic DTD" block (rev3) Patchwork
2019-11-16 1:48 ` [Intel-gfx] " Patchwork
2019-11-17 16:59 ` ✗ Fi.CI.IGT: failure " Patchwork
2019-11-17 16:59 ` [Intel-gfx] " Patchwork
2019-11-18 16:15 ` Matt Roper
2019-11-18 16:15 ` [Intel-gfx] " Matt Roper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87lfsdza72.fsf@intel.com \
--to=jani.nikula@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=matthew.d.roper@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox