All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser
@ 2022-06-14 23:30 Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 01/23] tools/intel_vbt_decode: update vbt defs from kernel Ville Syrjala
                   ` (24 more replies)
  0 siblings, 25 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Change the igt VBT parser to make copies of the BDB data blocks
(just as we do in the kernel parser now). This makes it less
hazardous/confusing if your block definition don't happent to
match reality. 

Eg. with the current scheme we could very easily misinterpret
random bits from other blocks/etc. as our block data by just
using an overly large structure for decoding. With the block
copies being  at least as big as out struct definitions the
worst that can happen is that we just decode some extra zeroes
rather than some random other bits.

The other thing I'm bringing over is the data pointer generation
stuff for modern VBTS (which lack the LFP data table pointes block).
That lets us keep decoding the LFP data block in exactly the
same way on old and new VBTs.

And naturally we have massive gaps in what data the tool actually
parses from the VBT. So lots of patches to just parse more stuff.
I didn't do an exhaustive study on this topic, so still probably
missing some useful things.

Ville Syrjälä (23):
  tools/intel_vbt_decode: update vbt defs from kernel
  tools/intel_vbt_decode: Decode more DVO ports
  tools/intel_vbt_decode: Decode mode HDMI data rates
  tools/intel_vbt_decode: Clean up SSC freq decoding
  tools/intel_vbt_decode: Decode DP max link rate
  tools/intel_vbt_decode: Unify panel type handling
  tools/intel_vbt_decode: Dump the block size
  tools/intel_vbt_decode: Decode the LFP power block
  tools/intel_vbt_decode: Dump the LVDS panel options
  tools/intel_vbt_decode: Decode new fast link training rate
  tools/intel_vbt_decode: Parse the old fast link training rate
    correctly
  tools/intel_vbt_decode: Parse the new eDP max link rate
  tools/intel_vbt_decode: Include BDB block header in hex dump
  tools/intel_vbt_decode: Make copies of the BDB blocks
  tools/intel_vbt_decode: Specify a minimum size for the BDB block copy
  tools/intel_vbt_decode: Convert LFP data pointers to be relative to
    the data block
  tools/intel_vbt_decode: Simplify LVDS data block parsing
  tools/intel_vbt_decode: Dump the panel PNP ID
  tools/intel_vbt_decode: Decode the end of the LFP data
  tools/intel_vbt_decode: Dump the LVDS data ptrs
  tools/intel_vbt_decode: Validate LVDS data table pointers
  tools/intel_vbt_decode: Generate LVDS data table pointes if not
    provided
  tools/intel_vbt_decode: Warn if we lack the full definiton of the BDB
    block

 tools/intel_vbt_decode.c | 919 ++++++++++++++++++++++++++++++++++-----
 tools/intel_vbt_defs.h   | 254 ++++++++---
 2 files changed, 1018 insertions(+), 155 deletions(-)

-- 
2.35.1

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 01/23] tools/intel_vbt_decode: update vbt defs from kernel
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 02/23] tools/intel_vbt_decode: Decode more DVO ports Ville Syrjala
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Sync up the the VBT definitions from kernel commit
24b8b74eb2eb ("drm/i915: Parse max link rate from the eDP BDB block")
and adjust the actual code to match.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c |   6 +-
 tools/intel_vbt_defs.h   | 254 +++++++++++++++++++++++++++++++--------
 2 files changed, 207 insertions(+), 53 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index b063af8469db..2419ee10bca9 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -460,7 +460,7 @@ static void dump_child_device(struct context *context,
 		printf("\t\tOffset to DTD buffer for edidless CHILD: 0x%02x\n", child->dtd_buf_ptr);
 		printf("\t\tEdidless EFP: %s\n", YESNO(child->edidless_efp));
 		printf("\t\tCompression enable: %s\n", YESNO(child->compression_enable));
-		printf("\t\tCompression method CPS: %s\n", YESNO(child->compression_method));
+		printf("\t\tCompression method CPS: %s\n", YESNO(child->compression_method_cps));
 		printf("\t\tDual pipe ganged eDP: %s\n", YESNO(child->ganged_edp));
 		printf("\t\tCompression structure index: 0x%02x)\n", child->compression_structure_index);
 		printf("\t\tSlave DDI port: 0x%02x (%s)\n", child->slave_port, dvo_port(child->slave_port));
@@ -634,9 +634,9 @@ static void dump_lvds_data(struct context *context,
 	ptrs = ptrs_block->data;
 
 	lfp_data_size =
-	    ptrs->ptr[1].fp_timing_offset - ptrs->ptr[0].fp_timing_offset;
+	    ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
 	dvo_offset =
-	    ptrs->ptr[0].dvo_timing_offset - ptrs->ptr[0].fp_timing_offset;
+	    ptrs->ptr[0].dvo_timing.offset - ptrs->ptr[0].fp_timing.offset;
 
 	num_entries = block->size / lfp_data_size;
 
diff --git a/tools/intel_vbt_defs.h b/tools/intel_vbt_defs.h
index 69a7cb1fa121..f8e5097222f2 100644
--- a/tools/intel_vbt_defs.h
+++ b/tools/intel_vbt_defs.h
@@ -111,10 +111,11 @@ enum bdb_block_id {
 	BDB_LVDS_LFP_DATA_PTRS		= 41,
 	BDB_LVDS_LFP_DATA		= 42,
 	BDB_LVDS_BACKLIGHT		= 43,
-	BDB_LVDS_POWER			= 44,
+	BDB_LFP_POWER			= 44,
 	BDB_MIPI_CONFIG			= 52,
 	BDB_MIPI_SEQUENCE		= 53,
 	BDB_COMPRESSION_PARAMETERS	= 56,
+	BDB_GENERIC_DTD			= 58,
 	BDB_SKIP			= 254, /* VBIOS private block, ignore */
 };
 
@@ -161,6 +162,14 @@ struct bdb_general_features {
 	u8 dp_ssc_freq:1;	/* SSC freq for PCH attached eDP */
 	u8 dp_ssc_dongle_supported:1;
 	u8 rsvd11:2; /* finish byte */
+
+	/* bits 6 */
+	u8 tc_hpd_retry_timeout:7; /* 242 */
+	u8 rsvd12:1;
+
+	/* bits 7 */
+	u8 afc_startup_config:2;/* 249 */
+	u8 rsvd13:6;
 } __packed;
 
 /*
@@ -225,32 +234,6 @@ struct bdb_general_features {
 #define DEVICE_TYPE_DIGITAL_OUTPUT	(1 << 1)
 #define DEVICE_TYPE_ANALOG_OUTPUT	(1 << 0)
 
-/*
- * Bits we care about when checking for DEVICE_TYPE_eDP. Depending on the
- * system, the other bits may or may not be set for eDP outputs.
- */
-#define DEVICE_TYPE_eDP_BITS \
-	(DEVICE_TYPE_INTERNAL_CONNECTOR |	\
-	 DEVICE_TYPE_MIPI_OUTPUT |		\
-	 DEVICE_TYPE_COMPOSITE_OUTPUT |		\
-	 DEVICE_TYPE_DUAL_CHANNEL |		\
-	 DEVICE_TYPE_LVDS_SIGNALING |		\
-	 DEVICE_TYPE_TMDS_DVI_SIGNALING |	\
-	 DEVICE_TYPE_VIDEO_SIGNALING |		\
-	 DEVICE_TYPE_DISPLAYPORT_OUTPUT |	\
-	 DEVICE_TYPE_ANALOG_OUTPUT)
-
-#define DEVICE_TYPE_DP_DUAL_MODE_BITS \
-	(DEVICE_TYPE_INTERNAL_CONNECTOR |	\
-	 DEVICE_TYPE_MIPI_OUTPUT |		\
-	 DEVICE_TYPE_COMPOSITE_OUTPUT |		\
-	 DEVICE_TYPE_LVDS_SIGNALING |		\
-	 DEVICE_TYPE_TMDS_DVI_SIGNALING |	\
-	 DEVICE_TYPE_VIDEO_SIGNALING |		\
-	 DEVICE_TYPE_DISPLAYPORT_OUTPUT |	\
-	 DEVICE_TYPE_DIGITAL_OUTPUT |		\
-	 DEVICE_TYPE_ANALOG_OUTPUT)
-
 #define DEVICE_CFG_NONE		0x00
 #define DEVICE_CFG_12BIT_DVOB	0x01
 #define DEVICE_CFG_12BIT_DVOC	0x02
@@ -292,8 +275,12 @@ struct bdb_general_features {
 #define DVO_PORT_HDMIE		12				/* 193 */
 #define DVO_PORT_DPF		13				/* N/A */
 #define DVO_PORT_HDMIF		14				/* N/A */
-#define DVO_PORT_DPG		15
-#define DVO_PORT_HDMIG		16
+#define DVO_PORT_DPG		15				/* 217 */
+#define DVO_PORT_HDMIG		16				/* 217 */
+#define DVO_PORT_DPH		17				/* 217 */
+#define DVO_PORT_HDMIH		18				/* 217 */
+#define DVO_PORT_DPI		19				/* 217 */
+#define DVO_PORT_HDMII		20				/* 217 */
 #define DVO_PORT_MIPIA		21				/* 171 */
 #define DVO_PORT_MIPIB		22				/* 171 */
 #define DVO_PORT_MIPIC		23				/* 171 */
@@ -302,6 +289,9 @@ struct bdb_general_features {
 #define HDMI_MAX_DATA_RATE_PLATFORM	0			/* 204 */
 #define HDMI_MAX_DATA_RATE_297		1			/* 204 */
 #define HDMI_MAX_DATA_RATE_165		2			/* 204 */
+#define HDMI_MAX_DATA_RATE_594		3			/* 249 */
+#define HDMI_MAX_DATA_RATE_340		4			/* 249 */
+#define HDMI_MAX_DATA_RATE_300		5			/* 249 */
 
 #define LEGACY_CHILD_DEVICE_CONFIG_SIZE		33
 
@@ -314,12 +304,23 @@ enum vbt_gmbus_ddi {
 	ICL_DDC_BUS_DDI_A = 0x1,
 	ICL_DDC_BUS_DDI_B,
 	TGL_DDC_BUS_DDI_C,
+	RKL_DDC_BUS_DDI_D = 0x3,
+	RKL_DDC_BUS_DDI_E,
 	ICL_DDC_BUS_PORT_1 = 0x4,
 	ICL_DDC_BUS_PORT_2,
 	ICL_DDC_BUS_PORT_3,
 	ICL_DDC_BUS_PORT_4,
 	TGL_DDC_BUS_PORT_5,
 	TGL_DDC_BUS_PORT_6,
+	ADLS_DDC_BUS_PORT_TC1 = 0x2,
+	ADLS_DDC_BUS_PORT_TC2,
+	ADLS_DDC_BUS_PORT_TC3,
+	ADLS_DDC_BUS_PORT_TC4,
+	ADLP_DDC_BUS_PORT_TC1 = 0x3,
+	ADLP_DDC_BUS_PORT_TC2,
+	ADLP_DDC_BUS_PORT_TC3,
+	ADLP_DDC_BUS_PORT_TC4
+
 };
 
 #define DP_AUX_A 0x40
@@ -329,11 +330,24 @@ enum vbt_gmbus_ddi {
 #define DP_AUX_E 0x50
 #define DP_AUX_F 0x60
 #define DP_AUX_G 0x70
+#define DP_AUX_H 0x80
+#define DP_AUX_I 0x90
 
-#define VBT_DP_MAX_LINK_RATE_HBR3	0
-#define VBT_DP_MAX_LINK_RATE_HBR2	1
-#define VBT_DP_MAX_LINK_RATE_HBR	2
-#define VBT_DP_MAX_LINK_RATE_LBR	3
+/* DP max link rate 216+ */
+#define BDB_216_VBT_DP_MAX_LINK_RATE_HBR3	0
+#define BDB_216_VBT_DP_MAX_LINK_RATE_HBR2	1
+#define BDB_216_VBT_DP_MAX_LINK_RATE_HBR	2
+#define BDB_216_VBT_DP_MAX_LINK_RATE_LBR	3
+
+/* DP max link rate 230+ */
+#define BDB_230_VBT_DP_MAX_LINK_RATE_DEF	0
+#define BDB_230_VBT_DP_MAX_LINK_RATE_LBR	1
+#define BDB_230_VBT_DP_MAX_LINK_RATE_HBR	2
+#define BDB_230_VBT_DP_MAX_LINK_RATE_HBR2	3
+#define BDB_230_VBT_DP_MAX_LINK_RATE_HBR3	4
+#define BDB_230_VBT_DP_MAX_LINK_RATE_UHBR10	5
+#define BDB_230_VBT_DP_MAX_LINK_RATE_UHBR13P5	6
+#define BDB_230_VBT_DP_MAX_LINK_RATE_UHBR20	7
 
 /*
  * The child device config, aka the display device data structure, provides a
@@ -368,7 +382,7 @@ struct child_device_config {
 			u16 dtd_buf_ptr;			/* 161 */
 			u8 edidless_efp:1;			/* 161 */
 			u8 compression_enable:1;		/* 198 */
-			u8 compression_method:1;		/* 198 */
+			u8 compression_method_cps:1;		/* 198 */
 			u8 ganged_edp:1;			/* 202 */
 			u8 reserved0:4;
 			u8 compression_structure_index:4;	/* 198 */
@@ -432,8 +446,8 @@ struct child_device_config {
 	u16 dp_gpio_pin_num;					/* 195 */
 	u8 dp_iboost_level:4;					/* 196 */
 	u8 hdmi_iboost_level:4;					/* 196 */
-	u8 dp_max_link_rate:2;					/* 216 CNL+ */
-	u8 dp_max_link_rate_reserved:6;				/* 216 */
+	u8 dp_max_link_rate:3;					/* 216/230 GLK+ */
+	u8 dp_max_link_rate_reserved:5;				/* 216/230 */
 } __packed;
 
 struct bdb_general_definitions {
@@ -461,7 +475,7 @@ struct bdb_general_definitions {
 	 * number = (block_size - sizeof(bdb_general_definitions))/
 	 *	     defs->child_dev_size;
 	 */
-	u8 devices[0];
+	u8 devices[];
 } __packed;
 
 /*
@@ -550,7 +564,9 @@ struct bdb_driver_features {
 	u16 tbt_enabled:1;
 	u16 psr_enabled:1;
 	u16 ips_enabled:1;
-	u16 reserved3:4;
+	u16 reserved3:1;
+	u16 dmrrs_enabled:1;
+	u16 reserved4:2;
 	u16 pc_feature_valid:1;
 } __packed;
 
@@ -622,6 +638,7 @@ struct bdb_sdvo_panel_dtds {
 #define EDP_30BPP	2
 #define EDP_RATE_1_62	0
 #define EDP_RATE_2_7	1
+#define EDP_RATE_5_4	2
 #define EDP_LANE_1	0
 #define EDP_LANE_2	1
 #define EDP_LANE_4	3
@@ -652,6 +669,16 @@ struct edp_full_link_params {
 	u8 vswing:4;
 } __packed;
 
+struct edp_apical_params {
+	u32 panel_oui;
+	u32 dpcd_base_address;
+	u32 dpcd_idridix_control_0;
+	u32 dpcd_option_select;
+	u32 dpcd_backlight;
+	u32 ambient_light;
+	u32 backlight_scale;
+} __packed;
+
 struct bdb_edp {
 	struct edp_power_seq power_seqs[16];
 	u32 color_depth;
@@ -667,6 +694,10 @@ struct bdb_edp {
 	struct edp_pwm_delays pwm_delays[16];			/* 186 */
 	u16 full_link_params_provided;				/* 199 */
 	struct edp_full_link_params full_link_params[16];	/* 199 */
+	u16 apical_enable;					/* 203 */
+	struct edp_apical_params apical_params[16];		/* 203 */
+	u16 edp_fast_link_training_rate[16];			/* 224 */
+	u16 edp_max_port_link_rate[16];				/* 244 */
 } __packed;
 
 /*
@@ -703,25 +734,28 @@ struct bdb_lvds_options {
 
 	u16 lcdvcc_s0_enable;					/* 200 */
 	u32 rotation;						/* 228 */
+	u32 position;						/* 240 */
 } __packed;
 
 /*
  * Block 41 - LFP Data Table Pointers
  */
+struct lvds_lfp_data_ptr_table {
+	u16 offset; /* offsets are from start of bdb */
+	u8 table_size;
+} __packed;
 
 /* LFP pointer table contains entries to the struct below */
 struct lvds_lfp_data_ptr {
-	u16 fp_timing_offset; /* offsets are from start of bdb */
-	u8 fp_table_size;
-	u16 dvo_timing_offset;
-	u8 dvo_table_size;
-	u16 panel_pnp_id_offset;
-	u8 pnp_table_size;
+	struct lvds_lfp_data_ptr_table fp_timing;
+	struct lvds_lfp_data_ptr_table dvo_timing;
+	struct lvds_lfp_data_ptr_table panel_pnp_id;
 } __packed;
 
 struct bdb_lvds_lfp_data_ptrs {
-	u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
+	u8 lvds_entries;
 	struct lvds_lfp_data_ptr ptr[16];
+	struct lvds_lfp_data_ptr_table panel_name; /* 156-163? */
 } __packed;
 
 /*
@@ -753,6 +787,11 @@ struct lvds_pnp_id {
 	u8 mfg_year;
 } __packed;
 
+/*
+ * For reference only. fp_timing has variable size so
+ * the data must be accessed using the data table pointers.
+ * Do not use this directly!
+ */
 struct lvds_lfp_data_entry {
 	struct lvds_fp_timing fp_timing;
 	struct lvds_dvo_timing dvo_timing;
@@ -763,6 +802,27 @@ struct bdb_lvds_lfp_data {
 	struct lvds_lfp_data_entry data[16];
 } __packed;
 
+struct lvds_lfp_panel_name {
+	u8 name[13];
+} __packed;
+
+struct lvds_lfp_black_border {
+	u8 top; /* 227 */
+	u8 bottom; /* 227 */
+	u8 left; /* 238 */
+	u8 right; /* 238 */
+} __packed;
+
+struct bdb_lvds_lfp_data_tail {
+	struct lvds_lfp_panel_name panel_name[16]; /* 156-163? */
+	u16 scaling_enable; /* 187 */
+	u8 seamless_drrs_min_refresh_rate[16]; /* 188 */
+	u8 pixel_overlap_count[16]; /* 208 */
+	struct lvds_lfp_black_border black_border[16]; /* 227 */
+	u16 dual_lfp_port_sync_enable; /* 231 */
+	u16 gpu_dithering_for_banding_artifacts; /* 245 */
+} __packed;
+
 /*
  * Block 43 - LFP Backlight Control Data Block
  */
@@ -775,7 +835,7 @@ struct lfp_backlight_data_entry {
 	u8 active_low_pwm:1;
 	u8 obsolete1:5;
 	u16 pwm_freq_hz;
-	u8 min_brightness;
+	u8 min_brightness; /* Obsolete from 234+ */
 	u8 obsolete2;
 	u8 obsolete3;
 } __packed;
@@ -785,11 +845,73 @@ struct lfp_backlight_control_method {
 	u8 controller:4;
 } __packed;
 
+struct lfp_brightness_level {
+	u16 level;
+	u16 reserved;
+} __packed;
+
+#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
+	offsetof(struct bdb_lfp_backlight_data, brightness_level)
+#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
+	offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
+
 struct bdb_lfp_backlight_data {
 	u8 entry_size;
 	struct lfp_backlight_data_entry data[16];
-	u8 level[16];
+	u8 level[16]; /* Obsolete from 234+ */
 	struct lfp_backlight_control_method backlight_control[16];
+	struct lfp_brightness_level brightness_level[16];		/* 234+ */
+	struct lfp_brightness_level brightness_min_level[16];		/* 234+ */
+	u8 brightness_precision_bits[16];				/* 236+ */
+	u16 hdr_dpcd_refresh_timeout[16];				/* 239+ */
+} __packed;
+
+/*
+ * Block 44 - LFP Power Conservation Features Block
+ */
+struct lfp_power_features {
+	u8 reserved1:1;
+	u8 power_conservation_pref:3;
+	u8 reserved2:1;
+	u8 lace_enabled_status:1;
+	u8 lace_support:1;
+	u8 als_enable:1;
+} __packed;
+
+struct als_data_entry {
+	u16 backlight_adjust;
+	u16 lux;
+} __packed;
+
+struct aggressiveness_profile_entry {
+	u8 dpst_aggressiveness : 4;
+	u8 lace_aggressiveness : 4;
+} __packed;
+
+struct aggressiveness_profile2_entry {
+	u8 opst_aggressiveness : 4;
+	u8 elp_aggressiveness : 4;
+} __packed;
+
+struct bdb_lfp_power {
+	struct lfp_power_features features;
+	struct als_data_entry als[5];
+	u8 lace_aggressiveness_profile:3;
+	u8 reserved1:5;
+	u16 dpst;
+	u16 psr;
+	u16 drrs;
+	u16 lace_support;
+	u16 adt;
+	u16 dmrrs;
+	u16 adb;
+	u16 lace_enabled_status;
+	struct aggressiveness_profile_entry aggressiveness[16];
+	u16 hobl; /* 232+ */
+	u16 vrr_feature_enabled; /* 233+ */
+	u16 elp; /* 247+ */
+	u16 opst; /* 247+ */
+	struct aggressiveness_profile2_entry aggressiveness2[16]; /* 247+ */
 } __packed;
 
 /*
@@ -799,8 +921,10 @@ struct bdb_lfp_backlight_data {
 #define MAX_MIPI_CONFIGURATIONS	6
 
 struct bdb_mipi_config {
-	struct mipi_config config[MAX_MIPI_CONFIGURATIONS];
-	struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS];
+	struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; /* 175 */
+	struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; /* 177 */
+	struct edp_pwm_delays pwm_delays[MAX_MIPI_CONFIGURATIONS]; /* 186 */
+	u8 pmic_i2c_bus_number[MAX_MIPI_CONFIGURATIONS]; /* 190 */
 } __packed;
 
 /*
@@ -809,7 +933,7 @@ struct bdb_mipi_config {
 
 struct bdb_mipi_sequence {
 	u8 version;
-	u8 data[0]; /* up to 6 variable length blocks */
+	u8 data[]; /* up to 6 variable length blocks */
 } __packed;
 
 /*
@@ -863,4 +987,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_ */
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 02/23] tools/intel_vbt_decode: Decode more DVO ports
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 01/23] tools/intel_vbt_decode: update vbt defs from kernel Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 03/23] tools/intel_vbt_decode: Decode mode HDMI data rates Ville Syrjala
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode the DP/HDMI DVO ports up to 'I'.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 2419ee10bca9..aff212a97399 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -379,6 +379,11 @@ static const char *dvo_port_names[] = {
 	[DVO_PORT_HDMIB] = "HDMI-B",
 	[DVO_PORT_HDMIC] = "HDMI-C",
 	[DVO_PORT_HDMID] = "HDMI-D",
+	[DVO_PORT_HDMIE] = "HDMI-E",
+	[DVO_PORT_HDMIF] = "HDMI-F",
+	[DVO_PORT_HDMIG] = "HDMI-G",
+	[DVO_PORT_HDMIH] = "HDMI-H",
+	[DVO_PORT_HDMII] = "HDMI-I",
 	[DVO_PORT_LVDS] = "LVDS",
 	[DVO_PORT_TV] = "TV",
 	[DVO_PORT_CRT] = "CRT",
@@ -387,7 +392,10 @@ static const char *dvo_port_names[] = {
 	[DVO_PORT_DPD] = "DP-D",
 	[DVO_PORT_DPA] = "DP-A",
 	[DVO_PORT_DPE] = "DP-E",
-	[DVO_PORT_HDMIE] = "HDMI-E",
+	[DVO_PORT_DPF] = "DP-F",
+	[DVO_PORT_DPG] = "DP-G",
+	[DVO_PORT_DPH] = "DP-H",
+	[DVO_PORT_DPI] = "DP-I",
 	[DVO_PORT_MIPIA] = "MIPI-A",
 	[DVO_PORT_MIPIB] = "MIPI-B",
 	[DVO_PORT_MIPIC] = "MIPI-C",
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 03/23] tools/intel_vbt_decode: Decode mode HDMI data rates
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 01/23] tools/intel_vbt_decode: update vbt defs from kernel Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 02/23] tools/intel_vbt_decode: Decode more DVO ports Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 04/23] tools/intel_vbt_decode: Clean up SSC freq decoding Ville Syrjala
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode new HDMI data rates.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index aff212a97399..c626f0e94659 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -430,6 +430,9 @@ static void dump_hmdi_max_data_rate(uint8_t hdmi_max_data_rate)
 		[HDMI_MAX_DATA_RATE_PLATFORM] = 0,
 		[HDMI_MAX_DATA_RATE_297] = 297,
 		[HDMI_MAX_DATA_RATE_165] = 165,
+		[HDMI_MAX_DATA_RATE_594] = 594,
+		[HDMI_MAX_DATA_RATE_340] = 340,
+		[HDMI_MAX_DATA_RATE_300] = 300,
 	};
 
 	if (hdmi_max_data_rate >= ARRAY_SIZE(max_data_rate))
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 04/23] tools/intel_vbt_decode: Clean up SSC freq decoding
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (2 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 03/23] tools/intel_vbt_decode: Decode mode HDMI data rates Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 05/23] tools/intel_vbt_decode: Decode DP max link rate Ville Syrjala
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Use the same logic as we use in the kernel to decode
the SSC frequency.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 46 +++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index c626f0e94659..a91273d89355 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -138,6 +138,19 @@ static struct bdb_block *find_section(struct context *context, int section_id)
 	return NULL;
 }
 
+static int decode_ssc_freq(struct context *context, bool alternate)
+{
+	switch (intel_gen(context->devid)) {
+	case 2:
+		return alternate ? 66 : 48;
+	case 3:
+	case 4:
+		return alternate ? 100 : 96;
+	default:
+		return alternate ? 100 : 120;
+	}
+}
+
 static void dump_general_features(struct context *context,
 				  const struct bdb_block *block)
 {
@@ -164,21 +177,10 @@ static void dump_general_features(struct context *context,
 	printf("\tDVO color flip required: %s\n", YESNO(features->color_flip));
 
 	printf("\tExternal VBT: %s\n", YESNO(features->download_ext_vbt));
-	printf("\tEnable SSC: %s\n", YESNO(features->enable_ssc));
-	if (features->enable_ssc) {
-		if (!context->devid)
-			printf("\tSSC frequency: <unknown platform>\n");
-		else if (IS_VALLEYVIEW(context->devid) ||
-			 IS_CHERRYVIEW(context->devid) ||
-			 IS_BROXTON(context->devid))
-			printf("\tSSC frequency: 100 MHz\n");
-		else if (HAS_PCH_SPLIT(context->devid))
-			printf("\tSSC frequency: %s\n", features->ssc_freq ?
-			       "100 MHz" : "120 MHz");
-		else
-			printf("\tSSC frequency: %s\n", features->ssc_freq ?
-			       "100 MHz (66 MHz on 855)" : "96 MHz (48 MHz on 855)");
-	}
+	printf("\tLVDS SSC Enable: %s\n", YESNO(features->enable_ssc));
+	printf("\tLVDS SSC frequency: %d MHz (0x%x)\n",
+	       decode_ssc_freq(context, features->ssc_freq),
+	       features->ssc_freq);
 	printf("\tLFP on override: %s\n",
 	       YESNO(features->enable_lfp_on_override));
 	printf("\tDisable SSC on clone: %s\n",
@@ -210,17 +212,9 @@ static void dump_general_features(struct context *context,
 	printf("\tIntegrated TV: %s\n", YESNO(features->int_tv_support));
 	printf("\tIntegrated EFP: %s\n", YESNO(features->int_efp_support));
 	printf("\tDP SSC enable: %s\n", YESNO(features->dp_ssc_enable));
-	if (features->dp_ssc_enable) {
-		if (IS_VALLEYVIEW(context->devid) || IS_CHERRYVIEW(context->devid) ||
-		    IS_BROXTON(context->devid))
-			printf("\tSSC frequency: 100 MHz\n");
-		else if (HAS_PCH_SPLIT(context->devid))
-			printf("\tSSC frequency: %s\n", features->dp_ssc_freq ?
-			       "100 MHz" : "120 MHz");
-		else
-			printf("\tSSC frequency: %s\n", features->dp_ssc_freq ?
-			       "100 MHz" : "96 MHz");
-	}
+	printf("\tDP SSC frequency: %d MHz (0x%x)\n",
+	       decode_ssc_freq(context, features->dp_ssc_freq),
+	       features->dp_ssc_freq);
 	printf("\tDP SSC dongle supported: %s\n", YESNO(features->dp_ssc_dongle_supported));
 }
 
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 05/23] tools/intel_vbt_decode: Decode DP max link rate
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (3 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 04/23] tools/intel_vbt_decode: Clean up SSC freq decoding Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 06/23] tools/intel_vbt_decode: Unify panel type handling Ville Syrjala
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode the child device DP max link rate stuff.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 50 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index a91273d89355..77de75068e12 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -441,6 +441,51 @@ static void dump_hmdi_max_data_rate(uint8_t hdmi_max_data_rate)
 		       hdmi_max_data_rate);
 }
 
+static int parse_dp_max_link_rate_216(uint8_t dp_max_link_rate)
+{
+	static const uint16_t max_link_rate[] = {
+		[BDB_216_VBT_DP_MAX_LINK_RATE_HBR3] = 810,
+		[BDB_216_VBT_DP_MAX_LINK_RATE_HBR2] = 540,
+		[BDB_216_VBT_DP_MAX_LINK_RATE_HBR] = 270,
+		[BDB_216_VBT_DP_MAX_LINK_RATE_LBR] = 162,
+	};
+
+	return max_link_rate[dp_max_link_rate & 0x3];
+}
+
+static int parse_dp_max_link_rate_230(uint8_t dp_max_link_rate)
+{
+	static const uint16_t max_link_rate[] = {
+		[BDB_230_VBT_DP_MAX_LINK_RATE_DEF] = 0,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_LBR] = 162,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_HBR] = 270,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_HBR2] = 540,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_HBR3] = 810,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_UHBR10] = 1000,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_UHBR13P5] = 1350,
+		[BDB_230_VBT_DP_MAX_LINK_RATE_UHBR20] = 2000,
+	};
+
+	return max_link_rate[dp_max_link_rate];
+}
+
+static void dump_dp_max_link_rate(uint16_t version, uint8_t dp_max_link_rate)
+{
+	int link_rate;
+
+	if (version >= 230)
+		link_rate = parse_dp_max_link_rate_230(dp_max_link_rate);
+	else
+		link_rate = parse_dp_max_link_rate_216(dp_max_link_rate);
+
+	if (link_rate == 0)
+		printf("\t\tDP max link rate: <platform max> (0x%02x)\n",
+		       dp_max_link_rate);
+	else
+		printf("\t\tDP max link rate: %g Gbps (0x%02x)\n",
+		       link_rate / 100.0f, dp_max_link_rate);
+}
+
 static void dump_child_device(struct context *context,
 			      const struct child_device_config *child)
 {
@@ -524,8 +569,11 @@ static void dump_child_device(struct context *context,
 		printf("\t\tIBoost level for HDMI: 0x%02x\n", child->hdmi_iboost_level);
 		printf("\t\tIBoost level for DP/eDP: 0x%02x\n", child->dp_iboost_level);
 	}
-}
 
+	if (context->bdb->version >= 216)
+		dump_dp_max_link_rate(context->bdb->version,
+				      child->dp_max_link_rate);
+}
 
 static void dump_child_devices(struct context *context, const uint8_t *devices,
 			       uint8_t child_dev_num, uint8_t child_dev_size)
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 06/23] tools/intel_vbt_decode: Unify panel type handling
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (4 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 05/23] tools/intel_vbt_decode: Decode DP max link rate Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 07/23] tools/intel_vbt_decode: Dump the block size Ville Syrjala
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Print the panel type(s) the same way in dump_lvds_data() as
elsewhere.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 77de75068e12..e16e12d0423c 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -702,16 +702,10 @@ static void dump_lvds_data(struct context *context,
 		const uint8_t *timing_data = lfp_data_ptr + dvo_offset;
 		const struct lvds_lfp_data_entry *lfp_data =
 		    (const struct lvds_lfp_data_entry *)lfp_data_ptr;
-		char marker;
 
 		if (i != context->panel_type && !context->dump_all_panel_types)
 			continue;
 
-		if (i == context->panel_type)
-			marker = '*';
-		else
-			marker = ' ';
-
 		hdisplay = _H_ACTIVE(timing_data);
 		hsyncstart = hdisplay + _H_SYNC_OFF(timing_data);
 		hsyncend = hsyncstart + _H_SYNC_WIDTH(timing_data);
@@ -723,8 +717,9 @@ static void dump_lvds_data(struct context *context,
 		vtotal = vdisplay + _V_BLANK(timing_data);
 		clock = _PIXEL_CLOCK(timing_data) / 1000;
 
-		printf("%c\tpanel type %02i: %dx%d clock %d\n", marker,
-		       i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res,
+		printf("\tPanel %d%s\n", i, context->panel_type == i ? " *" : "");
+		printf("\t\t%dx%d clock %d\n",
+		       lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res,
 		       _PIXEL_CLOCK(timing_data));
 		printf("\t\tinfo:\n");
 		printf("\t\t  LVDS: 0x%08lx\n",
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 07/23] tools/intel_vbt_decode: Dump the block size
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (5 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 06/23] tools/intel_vbt_decode: Unify panel type handling Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 08/23] tools/intel_vbt_decode: Decode the LFP power block Ville Syrjala
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Knowing the size of each block can help in figuring out what should
be in there. Let's dump that.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index e16e12d0423c..fdee0a41e071 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -1847,10 +1847,10 @@ static bool dump_section(struct context *context, int section_id)
 	}
 
 	if (dumper && dumper->name)
-		printf("BDB block %d - %s:\n", block->id, dumper->name);
+		printf("BDB block %d (%d bytes) - %s:\n", block->id, block->size, dumper->name);
 	else
-		printf("BDB block %d - Unknown, no decoding available:\n",
-		       block->id);
+		printf("BDB block %d (%d bytes) - Unknown, no decoding available:\n",
+		       block->id, block->size);
 
 	if (context->hexdump)
 		hex_dump_block(block);
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 08/23] tools/intel_vbt_decode: Decode the LFP power block
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (6 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 07/23] tools/intel_vbt_decode: Dump the block size Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 09/23] tools/intel_vbt_decode: Dump the LVDS panel options Ville Syrjala
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode the contents of the LFP power conservation block (44).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 85 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index fdee0a41e071..37f627561a1f 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -1067,6 +1067,86 @@ static void dump_psr(struct context *context,
 	}
 }
 
+static void dump_lfp_power(struct context *context,
+			   const struct bdb_block *block)
+{
+	const struct bdb_lfp_power *lfp_block = block->data;
+	int i;
+
+	printf("\tALS enable: %s\n",
+	       YESNO(lfp_block->features.als_enable));
+	printf("\tDisplay LACE support: %s\n",
+	       YESNO(lfp_block->features.lace_support));
+	printf("\tDefault Display LACE enabled status: %s\n",
+	       YESNO(lfp_block->features.lace_enabled_status));
+	printf("\tPower conservation preference level: %d\n",
+	       lfp_block->features.power_conservation_pref);
+
+	for (i = 0; i < 5; i++) {
+		printf("\tALS backlight adjust: %d\n",
+		       lfp_block->als[i].backlight_adjust);
+		printf("\tALS Lux: %d\n",
+		       lfp_block->als[i].lux);
+	}
+
+	printf("\tDisplay LACE aggressiveness profile: %d\n",
+	       lfp_block->lace_aggressiveness_profile);
+
+	if (context->bdb->version < 228)
+		return;
+
+	for (i = 0; i < 16; i++) {
+		if (i != context->panel_type && !context->dump_all_panel_types)
+			continue;
+
+		printf("\tPanel %d%s\n", i, context->panel_type == i ? " *" : "");
+
+		printf("\t\tDPST: %s\n",
+		       YESNO((lfp_block->dpst >> i) & 1));
+		printf("\t\tPSR: %s\n",
+		       YESNO((lfp_block->psr >> i) & 1));
+		printf("\t\tDRRS: %s\n",
+		       YESNO((lfp_block->drrs >> i) & 1));
+		printf("\t\tDisplay LACE support: %s\n",
+		       YESNO((lfp_block->lace_support >> i) & 1));
+		printf("\t\tADT: %s\n",
+		       YESNO((lfp_block->adt >> i) & 1));
+		printf("\t\tDMRRS: %s\n",
+		       YESNO((lfp_block->dmrrs >> i) & 1));
+		printf("\t\tADB: %s\n", YESNO((lfp_block->adb >> i) & 1));
+		printf("\t\tDefault Display LACE enabled: %s\n",
+		       YESNO((lfp_block->lace_enabled_status >> i) & 1));
+		printf("\t\tLACE Aggressiveness: %d\n",
+		       lfp_block->aggressiveness[i].lace_aggressiveness);
+		printf("\t\tDPST Aggressiveness: %d\n",
+		       lfp_block->aggressiveness[i].dpst_aggressiveness);
+
+		if (context->bdb->version < 232)
+			continue;
+
+		printf("\t\tEDP 4k/2k HOBL feature: %s\n",
+		       YESNO((lfp_block->hobl >> i) & 1));
+
+		if (context->bdb->version < 233)
+			continue;
+
+		printf("\t\tVRR feature: %s\n",
+		       YESNO((lfp_block->vrr_feature_enabled >> i) & 1));
+
+		if (context->bdb->version < 247)
+			continue;
+
+		printf("\t\tELP: %s\n",
+		       YESNO((lfp_block->elp >> i) & 1));
+		printf("\t\tOPST: %s\n",
+		       YESNO((lfp_block->opst >> i) & 1));
+		printf("\t\tELP Aggressiveness: %d\n",
+		       lfp_block->aggressiveness2[i].elp_aggressiveness);
+		printf("\t\tOPST Aggrgessiveness: %d\n",
+		       lfp_block->aggressiveness2[i].opst_aggressiveness);
+	}
+}
+
 static void
 print_detail_timing_data(const struct lvds_dvo_timing *dvo_timing)
 {
@@ -1761,6 +1841,11 @@ struct dumper dumpers[] = {
 		.name = "Backlight info block",
 		.dump = dump_backlight_info,
 	},
+	{
+		.id = BDB_LFP_POWER,
+		.name = "LFP power conservation features block",
+		.dump = dump_lfp_power,
+	},
 	{
 		.id = BDB_SDVO_LVDS_OPTIONS,
 		.name = "SDVO LVDS options block",
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 09/23] tools/intel_vbt_decode: Dump the LVDS panel options
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (7 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 08/23] tools/intel_vbt_decode: Decode the LFP power block Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 10/23] tools/intel_vbt_decode: Decode new fast link training rate Ville Syrjala
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode per-panel stuff from the LVDS options block.

Not at all sure which version have which fields since the spec
only goes back to v155. But earlier VBTs do have some of this
stuff already so going by block size instead for the older
stuff.

Here's a quick list from my VBT stash:
mgm version 108 -> 4 bytes
alv version 120 -> 4 bytes
cst version 134 -> 14 bytes
pnv version 144 -> 14 bytes
cl  version 142 -> 16 bytes
ctg version 155 -> 24 bytes

The pnv VBT is particularly interesting since it has a higher version
number that the cl VBT and yet has a smaller LVDS options block.
I guess the "Atom==let's not follow any rules" rule started already
back then.

All the more modern VBTs I have are 24 bytes (or more).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 95 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 37f627561a1f..48b56808d9fa 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -637,6 +637,34 @@ static void dump_legacy_child_devices(struct context *context,
 			   child_dev_num, defs->child_dev_size);
 }
 
+static const char * const channel_type[] = {
+	[0] = "automatic",
+	[1] = "single",
+	[2] = "dual",
+	[3] = "reserved",
+};
+
+static const char * const dps_type[] = {
+	[0] = "static DRRS",
+	[1] = "D2PO",
+	[2] = "seamless DRRS",
+	[3] = "reserved",
+};
+
+static const char * const blt_type[] = {
+	[0] = "default",
+	[1] = "CCFL",
+	[2] = "LED",
+	[3] = "reserved",
+};
+
+static const char * const pos_type[] = {
+	[0] = "inside shell",
+	[1] = "outside shell",
+	[2] = "reserved",
+	[3] = "reserved",
+};
+
 static void dump_lvds_options(struct context *context,
 			      const struct bdb_block *block)
 {
@@ -655,6 +683,73 @@ static void dump_lvds_options(struct context *context,
 	printf("\tPFIT enhanced text mode: %s\n",
 	       YESNO(options->pfit_text_mode_enhanced));
 	printf("\tPFIT mode: %d\n", options->pfit_mode);
+
+	if (block->size < 14)
+		return;
+
+	for (int i = 0; i < 16; i++) {
+		unsigned int val;
+
+		if (i != context->panel_type && !context->dump_all_panel_types)
+			continue;
+
+		printf("\tPanel %d%s\n", i, context->panel_type == i ? " *" : "");
+
+		val = (options->lvds_panel_channel_bits >> (i * 2)) & 3;
+		printf("\t\tChannel type: %s (0x%x)\n",
+		       channel_type[val], val);
+
+		val = (options->ssc_bits >> i) & 1;
+		printf("\t\tSSC: %s (0x%x)\n",
+		       YESNO(val), val);
+
+		val = (options->ssc_freq >> i) & 1;
+		printf("\t\tSSC frequency: %d MHz (0x%x)\n",
+		       decode_ssc_freq(context, val), val);
+
+		val = (options->ssc_ddt >> i) & 1;
+		printf("\t\tDisable SSC in dual display twin: %s (0x%x)\n",
+		       YESNO(val), val);
+
+		if (block->size < 16)
+			continue;
+
+		val = (options->panel_color_depth >> i) & 1;
+		printf("\t\tPanel color depth: %d (0x%x)\n",
+		       val ? 24 : 18, val);
+
+		if (block->size < 24)
+			continue;
+
+		val = (options->dps_panel_type_bits >> (i * 2)) & 3;
+		printf("\t\tDPS type: %s (0x%x)\n",
+		       dps_type[val], val);
+
+		val = (options->blt_control_type_bits >> (i * 2)) & 3;
+		printf("\t\tBacklight type: %s (0x%x)\n",
+		       blt_type[val], val);
+
+		if (context->bdb->version < 200)
+			continue;
+
+		val = (options->lcdvcc_s0_enable >> i) & 1;
+		printf("\t\tLCDVCC on during S0 state: %s (0x%x)\n",
+		       YESNO(val), val);
+
+		if (context->bdb->version < 228)
+			continue;
+
+		val = ((options->rotation) >> (i * 2)) & 3;
+		printf("\t\tPanel rotation: %d degrees (0x%x)\n",
+		       val * 90, val);
+
+		if (context->bdb->version < 240)
+			continue;
+
+		val = ((options->position) >> (i * 2)) & 3;
+		printf("\t\tPanel position: %s (0x%x)\n",
+		       pos_type[val], val);
+	}
 }
 
 static void dump_lvds_ptr_data(struct context *context,
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 10/23] tools/intel_vbt_decode: Decode new fast link training rate
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (8 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 09/23] tools/intel_vbt_decode: Dump the LVDS panel options Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 11/23] tools/intel_vbt_decode: Parse the old fast link training rate correctly Ville Syrjala
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode the fast link training link rate.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 48b56808d9fa..367e22caedfa 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -1097,6 +1097,13 @@ static void dump_edp(struct context *context,
 				break;
 			}
 		}
+
+		if (context->bdb->version >= 224) {
+			u16 rate = edp->edp_fast_link_training_rate[i];
+
+			printf("\t\teDP fast link training data rate: %g Gbps (0x%02x)\n",
+			       rate / 5000.0f, rate);
+		}
 	}
 }
 
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 11/23] tools/intel_vbt_decode: Parse the old fast link training rate correctly
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (9 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 10/23] tools/intel_vbt_decode: Decode new fast link training rate Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 12/23] tools/intel_vbt_decode: Parse the new eDP max link rate Ville Syrjala
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We're failing to parse the 5.4 Gbps value of the old
fast link training rate. Remedy it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 367e22caedfa..deaae9130b65 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -949,10 +949,21 @@ static void dump_edp(struct context *context,
 
 		printf("\t\tFast link params:\n");
 		printf("\t\t\trate: ");
-		if (edp->fast_link_params[i].rate == EDP_RATE_1_62)
-			printf("1.62G\n");
-		else if (edp->fast_link_params[i].rate == EDP_RATE_2_7)
-			printf("2.7G\n");
+		switch (edp->fast_link_params[i].rate) {
+		case EDP_RATE_1_62:
+			printf("1.62Gbps\n");
+			break;
+		case EDP_RATE_2_7:
+			printf("2.7Gbpc\n");
+			break;
+		case EDP_RATE_5_4:
+			printf("5.4Gbps\n");
+			break;
+		default:
+			printf("(unknonn value %d)\n",
+			       edp->fast_link_params[i].rate);
+			break;
+		}
 		printf("\t\t\tlanes: ");
 		switch (edp->fast_link_params[i].lanes) {
 		case EDP_LANE_1:
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 12/23] tools/intel_vbt_decode: Parse the new eDP max link rate
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (10 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 11/23] tools/intel_vbt_decode: Parse the old fast link training rate correctly Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 13/23] tools/intel_vbt_decode: Include BDB block header in hex dump Ville Syrjala
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

VBT version 244 onwards have a new eDP max link rate field.
Parse it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index deaae9130b65..cc9dd929db66 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -1115,6 +1115,13 @@ static void dump_edp(struct context *context,
 			printf("\t\teDP fast link training data rate: %g Gbps (0x%02x)\n",
 			       rate / 5000.0f, rate);
 		}
+
+		if (context->bdb->version >= 244) {
+			u16 rate = edp->edp_max_port_link_rate[i];
+
+			printf("\t\teDP max port link rate: %g Gbps (0x%02x)\n",
+			       rate / 5000.0f, rate);
+		}
 	}
 }
 
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 13/23] tools/intel_vbt_decode: Include BDB block header in hex dump
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (11 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 12/23] tools/intel_vbt_decode: Parse the new eDP max link rate Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 14/23] tools/intel_vbt_decode: Make copies of the BDB blocks Ville Syrjala
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Include the block header in the hex dump as well. Might
as well have the full data available in case we need to
diagnose some decoding failures.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index cc9dd929db66..deeb82050528 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -2031,7 +2031,7 @@ static void hex_dump(const void *data, uint32_t size)
 
 static void hex_dump_block(const struct bdb_block *block)
 {
-	hex_dump(block->data, block->size);
+	hex_dump(block->data - 3, 3 + block->size);
 }
 
 static bool dump_section(struct context *context, int section_id)
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 14/23] tools/intel_vbt_decode: Make copies of the BDB blocks
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (12 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 13/23] tools/intel_vbt_decode: Include BDB block header in hex dump Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 15/23] tools/intel_vbt_decode: Specify a minimum size for the BDB block copy Ville Syrjala
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Make a copy of the BDB blocks. For the moment we just do a
1:1 copy but later on we can specify a minimum size for
the copy and stop worrying about going out of bounds during
parsing in case the version checks are wrong of the VBT is
malformed.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 92 +++++++++++++++++++++++++---------------
 1 file changed, 57 insertions(+), 35 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index deeb82050528..48755164ec91 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -69,7 +69,7 @@ typedef uint64_t u64;
 struct bdb_block {
 	uint8_t id;
 	uint32_t size;
-	const void *data;
+	uint8_t data[];
 };
 
 struct context {
@@ -93,11 +93,16 @@ static uint32_t _get_blocksize(const uint8_t *block_base)
 		return *((const uint16_t *)(block_base + 1));
 }
 
-static struct bdb_block *find_section(struct context *context, int section_id)
+/* Get BDB block size give a pointer to data after Block ID and Block Size. */
+static u32 get_blocksize(const void *block_data)
+{
+	return _get_blocksize(block_data - 3);
+}
+
+static const void *find_raw_section(const struct context *context, int section_id)
 {
 	const struct bdb_header *bdb = context->bdb;
 	int length = context->size;
-	struct bdb_block *block;
 	const uint8_t *base = (const uint8_t *)bdb;
 	int index = 0;
 	uint32_t total, current_size;
@@ -109,12 +114,6 @@ static struct bdb_block *find_section(struct context *context, int section_id)
 	if (total > length)
 		total = length;
 
-	block = malloc(sizeof(*block));
-	if (!block) {
-		fprintf(stderr, "out of memory\n");
-		exit(EXIT_FAILURE);
-	}
-
 	/* walk the sections looking for section_id */
 	while (index + 3 < total) {
 		current_id = *(base + index);
@@ -124,20 +123,43 @@ static struct bdb_block *find_section(struct context *context, int section_id)
 		if (index + current_size > total)
 			return NULL;
 
-		if (current_id == section_id) {
-			block->id = current_id;
-			block->size = current_size;
-			block->data = base + index;
-			return block;
-		}
+		if (current_id == section_id)
+			return base + index;
 
 		index += current_size;
 	}
 
-	free(block);
 	return NULL;
 }
 
+static const void *block_data(const struct bdb_block *block)
+{
+	return block->data + 3;
+}
+
+static struct bdb_block *find_section(const struct context *context, int section_id)
+{
+	struct bdb_block *block;
+	const void *data;
+	size_t size;
+
+	data = find_raw_section(context, section_id);
+	if (!data)
+		return NULL;
+
+	size = get_blocksize(data);
+
+	block = calloc(1, sizeof(*block) + 3 + size);
+	if (!block)
+		return NULL;
+
+	block->id = section_id;
+	block->size = size;
+	memcpy(block->data, data - 3, 3 + size);
+
+	return block;
+}
+
 static int decode_ssc_freq(struct context *context, bool alternate)
 {
 	switch (intel_gen(context->devid)) {
@@ -154,7 +176,7 @@ static int decode_ssc_freq(struct context *context, bool alternate)
 static void dump_general_features(struct context *context,
 				  const struct bdb_block *block)
 {
-	const struct bdb_general_features *features = block->data;
+	const struct bdb_general_features *features = block_data(block);
 
 	printf("\tPanel fitting: ");
 	switch (features->panel_fitting) {
@@ -221,7 +243,7 @@ static void dump_general_features(struct context *context,
 static void dump_backlight_info(struct context *context,
 				const struct bdb_block *block)
 {
-	const struct bdb_lfp_backlight_data *backlight = block->data;
+	const struct bdb_lfp_backlight_data *backlight = block_data(block);
 	const struct lfp_backlight_data_entry *blc;
 	const struct lfp_backlight_control_method *control;
 	int i;
@@ -602,7 +624,7 @@ static void dump_child_devices(struct context *context, const uint8_t *devices,
 static void dump_general_definitions(struct context *context,
 				     const struct bdb_block *block)
 {
-	const struct bdb_general_definitions *defs = block->data;
+	const struct bdb_general_definitions *defs = block_data(block);
 	int child_dev_num;
 
 	child_dev_num = (block->size - sizeof(*defs)) / defs->child_dev_size;
@@ -625,7 +647,7 @@ static void dump_general_definitions(struct context *context,
 static void dump_legacy_child_devices(struct context *context,
 				      const struct bdb_block *block)
 {
-	const struct bdb_legacy_child_devices *defs = block->data;
+	const struct bdb_legacy_child_devices *defs = block_data(block);
 	int child_dev_num;
 
 	child_dev_num = (block->size - sizeof(*defs)) / defs->child_dev_size;
@@ -668,7 +690,7 @@ static const char * const pos_type[] = {
 static void dump_lvds_options(struct context *context,
 			      const struct bdb_block *block)
 {
-	const struct bdb_lvds_options *options = block->data;
+	const struct bdb_lvds_options *options = block_data(block);
 
 	if (context->panel_type == options->panel_type)
 		printf("\tPanel type: %d\n", options->panel_type);
@@ -755,7 +777,7 @@ static void dump_lvds_options(struct context *context,
 static void dump_lvds_ptr_data(struct context *context,
 			       const struct bdb_block *block)
 {
-	const struct bdb_lvds_lfp_data_ptrs *ptrs = block->data;
+	const struct bdb_lvds_lfp_data_ptrs *ptrs = block_data(block);
 
 	printf("\tNumber of entries: %d\n", ptrs->lvds_entries);
 }
@@ -763,7 +785,7 @@ static void dump_lvds_ptr_data(struct context *context,
 static void dump_lvds_data(struct context *context,
 			   const struct bdb_block *block)
 {
-	const struct bdb_lvds_lfp_data *lvds_data = block->data;
+	const struct bdb_lvds_lfp_data *lvds_data = block_data(block);
 	struct bdb_block *ptrs_block;
 	const struct bdb_lvds_lfp_data_ptrs *ptrs;
 	int num_entries;
@@ -779,7 +801,7 @@ static void dump_lvds_data(struct context *context,
 		return;
 	}
 
-	ptrs = ptrs_block->data;
+	ptrs = block_data(ptrs_block);
 
 	lfp_data_size =
 	    ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
@@ -840,7 +862,7 @@ static void dump_lvds_data(struct context *context,
 static void dump_driver_feature(struct context *context,
 				const struct bdb_block *block)
 {
-	const struct bdb_driver_features *feature = block->data;
+	const struct bdb_driver_features *feature = block_data(block);
 
 	printf("\tBoot Device Algorithm: %s\n", feature->boot_dev_algorithm ?
 	       "driver default" : "os default");
@@ -909,7 +931,7 @@ static void dump_driver_feature(struct context *context,
 static void dump_edp(struct context *context,
 		     const struct bdb_block *block)
 {
-	const struct bdb_edp *edp = block->data;
+	const struct bdb_edp *edp = block_data(block);
 	int bpp, msa;
 	int i;
 
@@ -1128,7 +1150,7 @@ static void dump_edp(struct context *context,
 static void dump_psr(struct context *context,
 		     const struct bdb_block *block)
 {
-	const struct bdb_psr *psr_block = block->data;
+	const struct bdb_psr *psr_block = block_data(block);
 	int i;
 	uint32_t psr2_tp_time;
 
@@ -1190,7 +1212,7 @@ static void dump_psr(struct context *context,
 static void dump_lfp_power(struct context *context,
 			   const struct bdb_block *block)
 {
-	const struct bdb_lfp_power *lfp_block = block->data;
+	const struct bdb_lfp_power *lfp_block = block_data(block);
 	int i;
 
 	printf("\tALS enable: %s\n",
@@ -1302,7 +1324,7 @@ print_detail_timing_data(const struct lvds_dvo_timing *dvo_timing)
 static void dump_sdvo_panel_dtds(struct context *context,
 				 const struct bdb_block *block)
 {
-	const struct lvds_dvo_timing *dvo_timing = block->data;
+	const struct lvds_dvo_timing *dvo_timing = block_data(block);
 	int n, count;
 
 	count = block->size / sizeof(struct lvds_dvo_timing);
@@ -1315,7 +1337,7 @@ static void dump_sdvo_panel_dtds(struct context *context,
 static void dump_sdvo_lvds_options(struct context *context,
 				   const struct bdb_block *block)
 {
-	const struct bdb_sdvo_lvds_options *options = block->data;
+	const struct bdb_sdvo_lvds_options *options = block_data(block);
 
 	printf("\tbacklight: %d\n", options->panel_backlight);
 	printf("\th40 type: %d\n", options->h40_set_panel_type);
@@ -1337,7 +1359,7 @@ static void dump_sdvo_lvds_options(struct context *context,
 static void dump_mipi_config(struct context *context,
 			     const struct bdb_block *block)
 {
-	const struct bdb_mipi_config *start = block->data;
+	const struct bdb_mipi_config *start = block_data(block);
 	const struct mipi_config *config;
 	const struct mipi_pps_data *pps;
 
@@ -1742,7 +1764,7 @@ static int goto_next_sequence_v3(const uint8_t *data, int index, int total)
 static void dump_mipi_sequence(struct context *context,
 			       const struct bdb_block *block)
 {
-	const struct bdb_mipi_sequence *sequence = block->data;
+	const struct bdb_mipi_sequence *sequence = block_data(block);
 	const uint8_t *data;
 	uint32_t seq_size;
 	int index = 0, i;
@@ -1843,7 +1865,7 @@ static const char *dsc_max_bpp(u8 value)
 static void dump_compression_parameters(struct context *context,
 					const struct bdb_block *block)
 {
-	const struct bdb_compression_parameters *dsc = block->data;
+	const struct bdb_compression_parameters *dsc = block_data(block);
 	const struct dsc_compression_parameters_entry *data;
 	int i;
 
@@ -1890,7 +1912,7 @@ static int get_panel_type(struct context *context)
 	if (!block)
 		return -1;
 
-	options = block->data;
+	options = block_data(block);
 	panel_type = options->panel_type;
 
 	free(block);
@@ -2031,7 +2053,7 @@ static void hex_dump(const void *data, uint32_t size)
 
 static void hex_dump_block(const struct bdb_block *block)
 {
-	hex_dump(block->data - 3, 3 + block->size);
+	hex_dump(block->data, 3 + block->size);
 }
 
 static bool dump_section(struct context *context, int section_id)
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 15/23] tools/intel_vbt_decode: Specify a minimum size for the BDB block copy
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (13 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 14/23] tools/intel_vbt_decode: Make copies of the BDB blocks Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 16/23] tools/intel_vbt_decode: Convert LFP data pointers to be relative to the data block Ville Syrjala
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Guarantee that we have enough memory allocated for the structure
we use to decode the BDB blocks. We no longer have to worry about
going out of bounds in case of malformed VBT or incorrect version
checks.

The BDB_SDVO_PANEL_DTDS and BDB_GENERIC_DTD code looks a bit
bit suspicious so those probably need a full review. Also
BDB_LVDS_LFP_DATA and BDB_LVDS_LFP_DATA_PTRS will need further
work due to the variable size nature of the data.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 47 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 48755164ec91..740940f9f29a 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -137,8 +137,53 @@ static const void *block_data(const struct bdb_block *block)
 	return block->data + 3;
 }
 
+static size_t block_min_size(const struct context *context, int section_id)
+{
+	switch (section_id) {
+	case BDB_GENERAL_FEATURES:
+		return sizeof(struct bdb_general_features);
+	case BDB_GENERAL_DEFINITIONS:
+		return sizeof(struct bdb_general_definitions);
+	case BDB_PSR:
+		return sizeof(struct bdb_psr);
+	case BDB_CHILD_DEVICE_TABLE:
+		return sizeof(struct bdb_legacy_child_devices);
+	case BDB_DRIVER_FEATURES:
+		return sizeof(struct bdb_driver_features);
+	case BDB_SDVO_LVDS_OPTIONS:
+		return sizeof(struct bdb_sdvo_lvds_options);
+	case BDB_SDVO_PANEL_DTDS:
+		/* FIXME? */
+		return 0;
+	case BDB_EDP:
+		return sizeof(struct bdb_edp);
+	case BDB_LVDS_OPTIONS:
+		return sizeof(struct bdb_lvds_options);
+	case BDB_LVDS_LFP_DATA_PTRS:
+		return sizeof(struct bdb_lvds_lfp_data_ptrs);
+	case BDB_LVDS_LFP_DATA:
+		return sizeof(struct bdb_lvds_lfp_data);
+	case BDB_LVDS_BACKLIGHT:
+		return sizeof(struct bdb_lfp_backlight_data);
+	case BDB_LFP_POWER:
+		return sizeof(struct bdb_lfp_power);
+	case BDB_MIPI_CONFIG:
+		return sizeof(struct bdb_mipi_config);
+	case BDB_MIPI_SEQUENCE:
+		return sizeof(struct bdb_mipi_sequence);
+	case BDB_COMPRESSION_PARAMETERS:
+		return sizeof(struct bdb_compression_parameters);
+	case BDB_GENERIC_DTD:
+		/* FIXME check spec */
+		return sizeof(struct bdb_generic_dtd);
+	default:
+		return 0;
+	}
+}
+
 static struct bdb_block *find_section(const struct context *context, int section_id)
 {
+	size_t min_size = block_min_size(context, section_id);
 	struct bdb_block *block;
 	const void *data;
 	size_t size;
@@ -149,7 +194,7 @@ static struct bdb_block *find_section(const struct context *context, int section
 
 	size = get_blocksize(data);
 
-	block = calloc(1, sizeof(*block) + 3 + size);
+	block = calloc(1, sizeof(*block) + 3 + max(size, min_size));
 	if (!block)
 		return NULL;
 
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 16/23] tools/intel_vbt_decode: Convert LFP data pointers to be relative to the data block
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (14 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 15/23] tools/intel_vbt_decode: Specify a minimum size for the BDB block copy Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 17/23] tools/intel_vbt_decode: Simplify LVDS data block parsing Ville Syrjala
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

For some crazy reason the LFP data pointer offsets are specified
as relative to the BDB header. That won't work with out private
BDB block copies, so let's convert them to be relative to the
start of the LFP data block.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 53 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 740940f9f29a..8f80c79ace4c 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -132,6 +132,21 @@ static const void *find_raw_section(const struct context *context, int section_i
 	return NULL;
 }
 
+/*
+ * Offset from the start of BDB to the start of the
+ * block data (just past the block header).
+ */
+static u32 raw_block_offset(const struct context *context, enum bdb_block_id section_id)
+{
+	const void *block;
+
+	block = find_raw_section(context, section_id);
+	if (!block)
+		return 0;
+
+	return block - (const void *)context->bdb;
+}
+
 static const void *block_data(const struct bdb_block *block)
 {
 	return block->data + 3;
@@ -181,6 +196,37 @@ static size_t block_min_size(const struct context *context, int section_id)
 	}
 }
 
+/* make the data table offsets relative to the data block */
+static bool fixup_lfp_data_ptrs(const struct context *context,
+				void *ptrs_block)
+{
+	struct bdb_lvds_lfp_data_ptrs *ptrs = ptrs_block;
+	u32 offset;
+	int i;
+
+	offset = raw_block_offset(context, BDB_LVDS_LFP_DATA);
+
+	for (i = 0; i < 16; i++) {
+		if (ptrs->ptr[i].fp_timing.offset < offset ||
+		    ptrs->ptr[i].dvo_timing.offset < offset ||
+		    ptrs->ptr[i].panel_pnp_id.offset < offset)
+			return false;
+
+		ptrs->ptr[i].fp_timing.offset -= offset;
+		ptrs->ptr[i].dvo_timing.offset -= offset;
+		ptrs->ptr[i].panel_pnp_id.offset -= offset;
+	}
+
+	if (ptrs->panel_name.table_size) {
+		if (ptrs->panel_name.offset < offset)
+			return false;
+
+		ptrs->panel_name.offset -= offset;
+	}
+
+	return true;
+}
+
 static struct bdb_block *find_section(const struct context *context, int section_id)
 {
 	size_t min_size = block_min_size(context, section_id);
@@ -202,6 +248,13 @@ static struct bdb_block *find_section(const struct context *context, int section
 	block->size = size;
 	memcpy(block->data, data - 3, 3 + size);
 
+	if (section_id == BDB_LVDS_LFP_DATA_PTRS &&
+	    !fixup_lfp_data_ptrs(context, 3 + block->data)) {
+		fprintf(stderr, "VBT has malformed LFP data table pointers\n");
+		free(block);
+		return NULL;
+	}
+
 	return block;
 }
 
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 17/23] tools/intel_vbt_decode: Simplify LVDS data block parsing
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (15 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 16/23] tools/intel_vbt_decode: Convert LFP data pointers to be relative to the data block Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 18/23] tools/intel_vbt_decode: Dump the panel PNP ID Ville Syrjala
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Get rid of the mess in the LVDS data block parsing and juse
use the offsets straight from the LVDS data table pointers
block.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 8f80c79ace4c..ef00a173d7af 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -883,40 +883,24 @@ static void dump_lvds_ptr_data(struct context *context,
 static void dump_lvds_data(struct context *context,
 			   const struct bdb_block *block)
 {
-	const struct bdb_lvds_lfp_data *lvds_data = block_data(block);
 	struct bdb_block *ptrs_block;
 	const struct bdb_lvds_lfp_data_ptrs *ptrs;
-	int num_entries;
 	int i;
 	int hdisplay, hsyncstart, hsyncend, htotal;
 	int vdisplay, vsyncstart, vsyncend, vtotal;
 	float clock;
-	int lfp_data_size, dvo_offset;
 
 	ptrs_block = find_section(context, BDB_LVDS_LFP_DATA_PTRS);
-	if (!ptrs_block) {
-		printf("No LVDS ptr block\n");
+	if (!ptrs_block)
 		return;
-	}
 
 	ptrs = block_data(ptrs_block);
 
-	lfp_data_size =
-	    ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
-	dvo_offset =
-	    ptrs->ptr[0].dvo_timing.offset - ptrs->ptr[0].fp_timing.offset;
-
-	num_entries = block->size / lfp_data_size;
-
-	printf("  Number of entries: %d (preferred block marked with '*')\n",
-	       num_entries);
-
-	for (i = 0; i < num_entries; i++) {
-		const uint8_t *lfp_data_ptr =
-		    (const uint8_t *) lvds_data->data + lfp_data_size * i;
-		const uint8_t *timing_data = lfp_data_ptr + dvo_offset;
-		const struct lvds_lfp_data_entry *lfp_data =
-		    (const struct lvds_lfp_data_entry *)lfp_data_ptr;
+	for (i = 0; i < 16; i++) {
+		const struct lvds_fp_timing *fp_timing =
+			block_data(block) + ptrs->ptr[i].fp_timing.offset;
+		const uint8_t *timing_data =
+			block_data(block) + ptrs->ptr[i].dvo_timing.offset;
 
 		if (i != context->panel_type && !context->dump_all_panel_types)
 			continue;
@@ -934,19 +918,19 @@ static void dump_lvds_data(struct context *context,
 
 		printf("\tPanel %d%s\n", i, context->panel_type == i ? " *" : "");
 		printf("\t\t%dx%d clock %d\n",
-		       lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res,
+		       fp_timing->x_res, fp_timing->y_res,
 		       _PIXEL_CLOCK(timing_data));
 		printf("\t\tinfo:\n");
 		printf("\t\t  LVDS: 0x%08lx\n",
-		       (unsigned long)lfp_data->fp_timing.lvds_reg_val);
+		       (unsigned long)fp_timing->lvds_reg_val);
 		printf("\t\t  PP_ON_DELAYS: 0x%08lx\n",
-		       (unsigned long)lfp_data->fp_timing.pp_on_reg_val);
+		       (unsigned long)fp_timing->pp_on_reg_val);
 		printf("\t\t  PP_OFF_DELAYS: 0x%08lx\n",
-		       (unsigned long)lfp_data->fp_timing.pp_off_reg_val);
+		       (unsigned long)fp_timing->pp_off_reg_val);
 		printf("\t\t  PP_DIVISOR: 0x%08lx\n",
-		       (unsigned long)lfp_data->fp_timing.pp_cycle_reg_val);
+		       (unsigned long)fp_timing->pp_cycle_reg_val);
 		printf("\t\t  PFIT: 0x%08lx\n",
-		       (unsigned long)lfp_data->fp_timing.pfit_reg_val);
+		       (unsigned long)fp_timing->pfit_reg_val);
 		printf("\t\ttimings: %d %d %d %d %d %d %d %d %.2f (%s)\n",
 		       hdisplay, hsyncstart, hsyncend, htotal,
 		       vdisplay, vsyncstart, vsyncend, vtotal, clock,
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 18/23] tools/intel_vbt_decode: Dump the panel PNP ID
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (16 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 17/23] tools/intel_vbt_decode: Simplify LVDS data block parsing Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 19/23] tools/intel_vbt_decode: Decode the end of the LFP data Ville Syrjala
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode the panel PNP ID from the LVDS data block.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index ef00a173d7af..e49831e2529d 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -33,6 +33,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -880,6 +881,18 @@ static void dump_lvds_ptr_data(struct context *context,
 	printf("\tNumber of entries: %d\n", ptrs->lvds_entries);
 }
 
+static char *decode_pnp_id(u16 mfg_name, char str[4])
+{
+	mfg_name = ntohs(mfg_name);
+
+	str[0] = '@' + ((mfg_name >> 10) & 0x1f);
+	str[1] = '@' + ((mfg_name >> 5) & 0x1f);
+	str[2] = '@' + ((mfg_name >> 0) & 0x1f);
+	str[3] = '\0';
+
+	return str;
+}
+
 static void dump_lvds_data(struct context *context,
 			   const struct bdb_block *block)
 {
@@ -901,6 +914,9 @@ static void dump_lvds_data(struct context *context,
 			block_data(block) + ptrs->ptr[i].fp_timing.offset;
 		const uint8_t *timing_data =
 			block_data(block) + ptrs->ptr[i].dvo_timing.offset;
+		const struct lvds_pnp_id *pnp_id =
+			block_data(block) + ptrs->ptr[i].panel_pnp_id.offset;
+		char mfg[4];
 
 		if (i != context->panel_type && !context->dump_all_panel_types)
 			continue;
@@ -936,6 +952,14 @@ static void dump_lvds_data(struct context *context,
 		       vdisplay, vsyncstart, vsyncend, vtotal, clock,
 		       (hsyncend > htotal || vsyncend > vtotal) ?
 		       "BAD!" : "good");
+
+		printf("\t\tPnP ID:\n");
+		printf("\t\t  Mfg name: %s (0x%x)\n",
+		       decode_pnp_id(pnp_id->mfg_name, mfg), pnp_id->mfg_name);
+		printf("\t\t  Product code: %u\n", pnp_id->product_code);
+		printf("\t\t  Serial: %u\n", pnp_id->serial);
+		printf("\t\t  Mfg week: %d\n", pnp_id->mfg_week);
+		printf("\t\t  Mfg year: %d\n", 1990 + pnp_id->mfg_year);
 	}
 
 	free(ptrs_block);
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 19/23] tools/intel_vbt_decode: Decode the end of the LFP data
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (17 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 18/23] tools/intel_vbt_decode: Dump the panel PNP ID Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 20/23] tools/intel_vbt_decode: Dump the LVDS data ptrs Ville Syrjala
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decode the tail end of the LFP data, if available.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 73 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index e49831e2529d..574aa25530fd 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -153,6 +153,30 @@ static const void *block_data(const struct bdb_block *block)
 	return block->data + 3;
 }
 
+static struct bdb_block *find_section(const struct context *context, int section_id);
+
+static size_t lfp_data_min_size(const struct context *context)
+{
+	const struct bdb_lvds_lfp_data_ptrs *ptrs;
+	struct bdb_block *ptrs_block;
+	size_t size;
+
+	ptrs_block = find_section(context, BDB_LVDS_LFP_DATA_PTRS);
+	if (!ptrs_block)
+		return 0;
+
+	ptrs = block_data(ptrs_block);
+
+	size = sizeof(struct bdb_lvds_lfp_data);
+	if (ptrs->panel_name.table_size)
+		size = max(size, ptrs->panel_name.offset +
+			   sizeof(struct bdb_lvds_lfp_data_tail));
+
+	free(ptrs_block);
+
+	return size;
+}
+
 static size_t block_min_size(const struct context *context, int section_id)
 {
 	switch (section_id) {
@@ -178,7 +202,7 @@ static size_t block_min_size(const struct context *context, int section_id)
 	case BDB_LVDS_LFP_DATA_PTRS:
 		return sizeof(struct bdb_lvds_lfp_data_ptrs);
 	case BDB_LVDS_LFP_DATA:
-		return sizeof(struct bdb_lvds_lfp_data);
+		return lfp_data_min_size(context);
 	case BDB_LVDS_BACKLIGHT:
 		return sizeof(struct bdb_lfp_backlight_data);
 	case BDB_LFP_POWER:
@@ -916,6 +940,8 @@ static void dump_lvds_data(struct context *context,
 			block_data(block) + ptrs->ptr[i].dvo_timing.offset;
 		const struct lvds_pnp_id *pnp_id =
 			block_data(block) + ptrs->ptr[i].panel_pnp_id.offset;
+		const struct bdb_lvds_lfp_data_tail *tail =
+			block_data(block) + ptrs->panel_name.offset;
 		char mfg[4];
 
 		if (i != context->panel_type && !context->dump_all_panel_types)
@@ -960,6 +986,51 @@ static void dump_lvds_data(struct context *context,
 		printf("\t\t  Serial: %u\n", pnp_id->serial);
 		printf("\t\t  Mfg week: %d\n", pnp_id->mfg_week);
 		printf("\t\t  Mfg year: %d\n", 1990 + pnp_id->mfg_year);
+
+		if (!ptrs->panel_name.table_size)
+			continue;
+
+		printf("\t\tPanel name: %.*s\n",
+		       (int)sizeof(tail->panel_name[0].name), tail->panel_name[i].name);
+
+		if (context->bdb->version < 187)
+			continue;
+
+		printf("\t\tScaling enable: %s\n",
+		       YESNO((tail->scaling_enable >> i) & 1));
+
+		if (context->bdb->version < 188)
+			continue;
+
+		printf("\t\tSeamless DRRS min refresh rate: %d\n",
+		       tail->seamless_drrs_min_refresh_rate[i]);
+
+		if (context->bdb->version < 208)
+			continue;
+
+		printf("\t\tPixel overlap count: %d\n",
+		       tail->pixel_overlap_count[i]);
+
+		if (context->bdb->version < 227)
+			continue;
+
+		printf("\t\tBlack border:\n");
+		printf("\t\t  Top: %d\n", tail->black_border[i].top);
+		printf("\t\t  Bottom: %d\n", tail->black_border[i].top);
+		printf("\t\t  Left: %d\n", tail->black_border[i].left);
+		printf("\t\t  Right: %d\n", tail->black_border[i].right);
+
+		if (context->bdb->version < 231)
+			continue;
+
+		printf("\t\tDual LFP port sync enable: %s\n",
+		       YESNO((tail->dual_lfp_port_sync_enable >> i) & 1));
+
+		if (context->bdb->version < 245)
+			continue;
+
+		printf("\t\tGPU dithering for banding artifacts: %s\n",
+		       YESNO((tail->gpu_dithering_for_banding_artifacts >> i) & 1));
 	}
 
 	free(ptrs_block);
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 20/23] tools/intel_vbt_decode: Dump the LVDS data ptrs
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (18 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 19/23] tools/intel_vbt_decode: Decode the end of the LFP data Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 21/23] tools/intel_vbt_decode: Validate LVDS data table pointers Ville Syrjala
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decoede the LVDS data pointers. The offsets are specificed from
the start of the whole VBT, but we've fixed them up to be relative
to the start of the block already. For human parsing printing
them as relative from the start of the block seems more useful
anywya.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 574aa25530fd..29857e4154e8 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -903,6 +903,39 @@ static void dump_lvds_ptr_data(struct context *context,
 	const struct bdb_lvds_lfp_data_ptrs *ptrs = block_data(block);
 
 	printf("\tNumber of entries: %d\n", ptrs->lvds_entries);
+
+	for (int i = 0; i < 16; i++) {
+		if (i != context->panel_type && !context->dump_all_panel_types)
+			continue;
+
+		printf("\tPanel %d%s\n", i, context->panel_type == i ? " *" : "");
+
+		if (ptrs->lvds_entries >= 1) {
+			printf("\t\tFP timing offset: %d\n",
+			       ptrs->ptr[i].fp_timing.offset);
+			printf("\t\tFP timing table size: %d\n",
+			       ptrs->ptr[i].fp_timing.table_size);
+		}
+		if (ptrs->lvds_entries >= 2) {
+			printf("\t\tDVO timing offset: %d\n",
+			       ptrs->ptr[i].dvo_timing.offset);
+			printf("\t\tDVO timing table size: %d\n",
+			       ptrs->ptr[i].dvo_timing.table_size);
+		}
+		if (ptrs->lvds_entries >= 3) {
+			printf("\t\tPanel PnP ID offset: %d\n",
+			       ptrs->ptr[i].panel_pnp_id.offset);
+			printf("\t\tPanel PnP ID table size: %d\n",
+			       ptrs->ptr[i].panel_pnp_id.table_size);
+		}
+	}
+
+	if (ptrs->panel_name.table_size) {
+		printf("\tPanel name offset: %d\n",
+		       ptrs->panel_name.offset);
+		printf("\tPanel name table size: %d\n",
+		       ptrs->panel_name.table_size);
+	}
 }
 
 static char *decode_pnp_id(u16 mfg_name, char str[4])
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 21/23] tools/intel_vbt_decode: Validate LVDS data table pointers
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (19 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 20/23] tools/intel_vbt_decode: Dump the LVDS data ptrs Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 22/23] tools/intel_vbt_decode: Generate LVDS data table pointes if not provided Ville Syrjala
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Do a reasonably exhaustive check to make sure the LVDS
data table pointers are sane.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 91 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 29857e4154e8..2ec9990279d9 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -148,6 +148,18 @@ static u32 raw_block_offset(const struct context *context, enum bdb_block_id sec
 	return block - (const void *)context->bdb;
 }
 
+/* size of the block excluding the header */
+static u32 raw_block_size(const struct context *context, enum bdb_block_id section_id)
+{
+	const void *block;
+
+	block = find_raw_section(context, section_id);
+	if (!block)
+		return 0;
+
+	return get_blocksize(block);
+}
+
 static const void *block_data(const struct bdb_block *block)
 {
 	return block->data + 3;
@@ -221,6 +233,83 @@ static size_t block_min_size(const struct context *context, int section_id)
 	}
 }
 
+static bool validate_lfp_data_ptrs(const struct context *context,
+				   const struct bdb_lvds_lfp_data_ptrs *ptrs)
+{
+	int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
+	int data_block_size, lfp_data_size;
+	int i;
+
+	data_block_size = raw_block_size(context, BDB_LVDS_LFP_DATA);
+	if (data_block_size == 0)
+		return false;
+
+	/* always 3 indicating the presence of fp_timing+dvo_timing+panel_pnp_id */
+	if (ptrs->lvds_entries != 3)
+		return false;
+
+	fp_timing_size = ptrs->ptr[0].fp_timing.table_size;
+	dvo_timing_size = ptrs->ptr[0].dvo_timing.table_size;
+	panel_pnp_id_size = ptrs->ptr[0].panel_pnp_id.table_size;
+	panel_name_size = ptrs->panel_name.table_size;
+
+	/* fp_timing has variable size */
+	if (fp_timing_size < 32 ||
+	    dvo_timing_size != sizeof(struct lvds_dvo_timing) ||
+	    panel_pnp_id_size != sizeof(struct lvds_pnp_id))
+		return false;
+
+	/* panel_name is not present in old VBTs */
+	if (panel_name_size != 0 &&
+	    panel_name_size != sizeof(struct lvds_lfp_panel_name))
+		return false;
+
+	lfp_data_size = ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
+	if (16 * lfp_data_size > data_block_size)
+		return false;
+
+	/*
+	 * Except for vlv/chv machines all real VBTs seem to have 6
+	 * unaccounted bytes in the fp_timing table. And it doesn't
+	 * appear to be a really intentional hole as the fp_timing
+	 * 0xffff terminator is always within those 6 missing bytes.
+	 */
+	if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size &&
+	    fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
+		return false;
+
+	if (ptrs->ptr[0].fp_timing.offset + fp_timing_size > ptrs->ptr[0].dvo_timing.offset ||
+	    ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
+	    ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
+		return false;
+
+	/* make sure the table entries have uniform size */
+	for (i = 1; i < 16; i++) {
+		if (ptrs->ptr[i].fp_timing.table_size != fp_timing_size ||
+		    ptrs->ptr[i].dvo_timing.table_size != dvo_timing_size ||
+		    ptrs->ptr[i].panel_pnp_id.table_size != panel_pnp_id_size)
+			return false;
+
+		if (ptrs->ptr[i].fp_timing.offset - ptrs->ptr[i-1].fp_timing.offset != lfp_data_size ||
+		    ptrs->ptr[i].dvo_timing.offset - ptrs->ptr[i-1].dvo_timing.offset != lfp_data_size ||
+		    ptrs->ptr[i].panel_pnp_id.offset - ptrs->ptr[i-1].panel_pnp_id.offset != lfp_data_size)
+			return false;
+	}
+
+	/* make sure the tables fit inside the data block */
+	for (i = 0; i < 16; i++) {
+		if (ptrs->ptr[i].fp_timing.offset + fp_timing_size > data_block_size ||
+		    ptrs->ptr[i].dvo_timing.offset + dvo_timing_size > data_block_size ||
+		    ptrs->ptr[i].panel_pnp_id.offset + panel_pnp_id_size > data_block_size)
+			return false;
+	}
+
+	if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size)
+		return false;
+
+	return true;
+}
+
 /* make the data table offsets relative to the data block */
 static bool fixup_lfp_data_ptrs(const struct context *context,
 				void *ptrs_block)
@@ -249,7 +338,7 @@ static bool fixup_lfp_data_ptrs(const struct context *context,
 		ptrs->panel_name.offset -= offset;
 	}
 
-	return true;
+	return validate_lfp_data_ptrs(context, ptrs);
 }
 
 static struct bdb_block *find_section(const struct context *context, int section_id)
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 22/23] tools/intel_vbt_decode: Generate LVDS data table pointes if not provided
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (20 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 21/23] tools/intel_vbt_decode: Validate LVDS data table pointers Ville Syrjala
@ 2022-06-14 23:30 ` Ville Syrjala
  2022-06-14 23:31 ` [igt-dev] [PATCH i-g-t 23/23] tools/intel_vbt_decode: Warn if we lack the full definiton of the BDB block Ville Syrjala
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:30 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Modern VBTs (at least observed on TGL machines) no longer provide the
LVDS data table pointers block. Thus we can't currently decode the
contents of the LVDS data table block.

I see two options how to handle this:
1) Just hardocode the offsets/sizes (+ some checks to make sure the
   hardcoded values makes sense)
2) Deduce the offsets/sizes from the actual LVDS data table block
   contents

I've chosen option 2 here. The fp_timing table 0xffff terminator
is what allows us to do this. We just look up the first two
of those from the LVDS data block and calculate the offsets/sizes
from there. Only the fp_timing entries should have a variable size,
and the dvo_timings and panel_pnp_id have fixed size (in fact IIRC
they are 1:1 match for the equivalent EDID stuff).

This is the same thing we do in the kernel parser as well since
commit a87d0a847607 ("drm/i915/bios: Generate LFP data table
pointers if the VBT lacks them")

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 128 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 127 insertions(+), 1 deletion(-)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index 2ec9990279d9..e45bab4a3e01 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -189,6 +189,121 @@ static size_t lfp_data_min_size(const struct context *context)
 	return size;
 }
 
+static const uint8_t *find_fp_timing_terminator(const uint8_t *data, int size)
+{
+	if (!data)
+		return NULL;
+
+	for (int i = 0; i < size - 1; i++) {
+		if (data[i] == 0xff && data[i+1] == 0xff)
+			return &data[i];
+	}
+
+	return NULL;
+}
+
+static int make_lvds_data_ptr(struct lvds_lfp_data_ptr_table *table,
+			      int table_size, int total_size)
+{
+	if (total_size < table_size)
+		return total_size;
+
+	table->table_size = table_size;
+	table->offset = total_size - table_size;
+
+	return total_size - table_size;
+}
+
+static void next_lvds_data_ptr(struct lvds_lfp_data_ptr_table *next,
+			       const struct lvds_lfp_data_ptr_table *prev,
+			       int size)
+{
+	next->table_size = prev->table_size;
+	next->offset = prev->offset + size;
+}
+
+static void *generate_lvds_data_ptrs(const struct context *context)
+{
+	int size, table_size, block_size, offset;
+	const void *t0, *t1, *block;
+	struct bdb_lvds_lfp_data_ptrs *ptrs;
+	void *ptrs_block;
+
+	block = find_raw_section(context, BDB_LVDS_LFP_DATA);
+	if (!block)
+		return NULL;
+
+	block_size = get_blocksize(block);
+
+	size = block_size;
+	t0 = find_fp_timing_terminator(block, size);
+	if (!t0)
+		return NULL;
+
+	size -= t0 - block - 2;
+	t1 = find_fp_timing_terminator(t0 + 2, size);
+	if (!t1)
+		return NULL;
+
+	size = t1 - t0;
+	if (size * 16 > block_size)
+		return NULL;
+
+	ptrs_block = calloc(1, sizeof(*ptrs) + 3);
+	if (!ptrs_block)
+		return NULL;
+
+	*(uint8_t *)(ptrs_block + 0) = BDB_LVDS_LFP_DATA_PTRS;
+	*(uint16_t *)(ptrs_block + 1) = sizeof(*ptrs);
+	ptrs = ptrs_block + 3;
+
+	table_size = sizeof(struct lvds_pnp_id);
+	size = make_lvds_data_ptr(&ptrs->ptr[0].panel_pnp_id, table_size, size);
+
+	table_size = sizeof(struct lvds_dvo_timing);
+	size = make_lvds_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
+
+	table_size = t0 - block + 2;
+	size = make_lvds_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
+
+	if (ptrs->ptr[0].fp_timing.table_size)
+		ptrs->lvds_entries++;
+	if (ptrs->ptr[0].dvo_timing.table_size)
+		ptrs->lvds_entries++;
+	if (ptrs->ptr[0].panel_pnp_id.table_size)
+		ptrs->lvds_entries++;
+
+	if (size != 0 || ptrs->lvds_entries != 3)
+		return NULL;
+
+	size = t1 - t0;
+	for (int i = 1; i < 16; i++) {
+		next_lvds_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
+		next_lvds_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
+		next_lvds_data_ptr(&ptrs->ptr[i].panel_pnp_id, &ptrs->ptr[i-1].panel_pnp_id, size);
+	}
+
+	size = t1 - t0;
+	table_size = sizeof(struct lvds_lfp_panel_name);
+
+	if (16 * (size + table_size) <= block_size) {
+		ptrs->panel_name.table_size = table_size;
+		ptrs->panel_name.offset = size * 16;
+	}
+
+	offset = block - (const void *)context->bdb;
+	for (int i = 0; i < 16; i++) {
+		ptrs->ptr[i].fp_timing.offset += offset;
+		ptrs->ptr[i].dvo_timing.offset += offset;
+		ptrs->ptr[i].panel_pnp_id.offset += offset;
+	}
+
+	if (ptrs->panel_name.offset)
+		ptrs->panel_name.offset += offset;
+
+	return ptrs_block;
+}
+
 static size_t block_min_size(const struct context *context, int section_id)
 {
 	switch (section_id) {
@@ -345,23 +460,34 @@ static struct bdb_block *find_section(const struct context *context, int section
 {
 	size_t min_size = block_min_size(context, section_id);
 	struct bdb_block *block;
+	void *temp_block = NULL;
 	const void *data;
 	size_t size;
 
 	data = find_raw_section(context, section_id);
+	if (!data && section_id == BDB_LVDS_LFP_DATA_PTRS) {
+		printf("Generating LVDS data table pointers\n");
+		temp_block = generate_lvds_data_ptrs(context);
+		if (temp_block)
+			data = temp_block + 3;
+	}
 	if (!data)
 		return NULL;
 
 	size = get_blocksize(data);
 
 	block = calloc(1, sizeof(*block) + 3 + max(size, min_size));
-	if (!block)
+	if (!block) {
+		free(temp_block);
 		return NULL;
+	}
 
 	block->id = section_id;
 	block->size = size;
 	memcpy(block->data, data - 3, 3 + size);
 
+	free(temp_block);
+
 	if (section_id == BDB_LVDS_LFP_DATA_PTRS &&
 	    !fixup_lfp_data_ptrs(context, 3 + block->data)) {
 		fprintf(stderr, "VBT has malformed LFP data table pointers\n");
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] [PATCH i-g-t 23/23] tools/intel_vbt_decode: Warn if we lack the full definiton of the BDB block
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (21 preceding siblings ...)
  2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 22/23] tools/intel_vbt_decode: Generate LVDS data table pointes if not provided Ville Syrjala
@ 2022-06-14 23:31 ` Ville Syrjala
  2022-06-15  0:24 ` [igt-dev] ✗ Fi.CI.BAT: failure for tools/intel_vbt_decode: Improve the parser Patchwork
  2022-06-15  6:44 ` [igt-dev] [PATCH i-g-t 00/23] " Jani Nikula
  24 siblings, 0 replies; 28+ messages in thread
From: Ville Syrjala @ 2022-06-14 23:31 UTC (permalink / raw)
  To: igt-dev

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Warn in case out BDB block definition is smaller than what
the VBT has. That is an indication that we are potentially
forgetting to decode some useful new data.

We exclude blocks 2,11,22 from this since we don't have
a sensible min size for them.

We also limit this to modernish VBTs (155+) since some
old stuff doesn't really conform (eg. my cst with version
134 has a 9 byte block 1 even though our min size for it
is 7 bytes, and all the other oldish machines have block
1 only made up of of 4 or 5 bytes).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tools/intel_vbt_decode.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/intel_vbt_decode.c b/tools/intel_vbt_decode.c
index e45bab4a3e01..5494a34bdca3 100644
--- a/tools/intel_vbt_decode.c
+++ b/tools/intel_vbt_decode.c
@@ -476,6 +476,15 @@ static struct bdb_block *find_section(const struct context *context, int section
 
 	size = get_blocksize(data);
 
+	/* expect to have the full definition for each block with modern VBTs */
+	if (min_size && size > min_size &&
+	    section_id != BDB_CHILD_DEVICE_TABLE &&
+	    section_id != BDB_SDVO_LVDS_OPTIONS &&
+	    section_id != BDB_GENERAL_DEFINITIONS &&
+	    context->bdb->version >= 155)
+		fprintf(stderr, "Block %d min size %zu less than block size %zu\n",
+			section_id, min_size, size);
+
 	block = calloc(1, sizeof(*block) + 3 + max(size, min_size));
 	if (!block) {
 		free(temp_block);
-- 
2.35.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [igt-dev] ✗ Fi.CI.BAT: failure for tools/intel_vbt_decode: Improve the parser
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (22 preceding siblings ...)
  2022-06-14 23:31 ` [igt-dev] [PATCH i-g-t 23/23] tools/intel_vbt_decode: Warn if we lack the full definiton of the BDB block Ville Syrjala
@ 2022-06-15  0:24 ` Patchwork
  2022-06-15  6:44 ` [igt-dev] [PATCH i-g-t 00/23] " Jani Nikula
  24 siblings, 0 replies; 28+ messages in thread
From: Patchwork @ 2022-06-15  0:24 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 8390 bytes --]

== Series Details ==

Series: tools/intel_vbt_decode: Improve the parser
URL   : https://patchwork.freedesktop.org/series/105133/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_11758 -> IGTPW_7311
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_7311 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_7311, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/index.html

Participating hosts (43 -> 42)
------------------------------

  Additional (2): fi-hsw-4770 bat-dg2-9 
  Missing    (3): bat-atsm-1 fi-bdw-samus fi-pnv-d510 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_7311:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_module_load@load:
    - fi-hsw-4770:        NOTRUN -> [DMESG-WARN][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-hsw-4770/igt@i915_module_load@load.html

  
Known issues
------------

  Here are the changes found in IGTPW_7311 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@gem_migrate:
    - fi-bdw-5557u:       [PASS][2] -> [INCOMPLETE][3] ([i915#5716])
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/fi-bdw-5557u/igt@i915_selftest@live@gem_migrate.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-bdw-5557u/igt@i915_selftest@live@gem_migrate.html

  * igt@i915_selftest@live@gt_lrc:
    - fi-bsw-n3050:       [PASS][4] -> [DMESG-FAIL][5] ([i915#2373])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/fi-bsw-n3050/igt@i915_selftest@live@gt_lrc.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-bsw-n3050/igt@i915_selftest@live@gt_lrc.html

  * igt@i915_selftest@live@hangcheck:
    - bat-dg1-6:          [PASS][6] -> [DMESG-FAIL][7] ([i915#4494] / [i915#4957])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/bat-dg1-6/igt@i915_selftest@live@hangcheck.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/bat-dg1-6/igt@i915_selftest@live@hangcheck.html

  * igt@i915_suspend@basic-s2idle-without-i915:
    - bat-dg1-5:          NOTRUN -> [INCOMPLETE][8] ([i915#6011])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/bat-dg1-5/igt@i915_suspend@basic-s2idle-without-i915.html

  * igt@kms_busy@basic@modeset:
    - fi-tgl-u2:          [PASS][9] -> [DMESG-WARN][10] ([i915#402])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/fi-tgl-u2/igt@kms_busy@basic@modeset.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-tgl-u2/igt@kms_busy@basic@modeset.html

  * igt@kms_chamelium@common-hpd-after-suspend:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][11] ([fdo#109271] / [fdo#111827])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-bsw-n3050/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][12] ([fdo#109271])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-bsw-n3050/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@runner@aborted:
    - fi-hsw-4770:        NOTRUN -> [FAIL][13] ([i915#4312] / [i915#5594])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-hsw-4770/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@i915_pm_rpm@module-reload:
    - bat-adlp-4:         [DMESG-WARN][14] ([i915#3576]) -> [PASS][15] +2 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/bat-adlp-4/igt@i915_pm_rpm@module-reload.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/bat-adlp-4/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@execlists:
    - fi-bsw-n3050:       [INCOMPLETE][16] ([i915#2940]) -> [PASS][17]
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/fi-bsw-n3050/igt@i915_selftest@live@execlists.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-bsw-n3050/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@live@gt_engines:
    - bat-dg1-5:          [INCOMPLETE][18] ([i915#4418]) -> [PASS][19]
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/bat-dg1-5/igt@i915_selftest@live@gt_engines.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/bat-dg1-5/igt@i915_selftest@live@gt_engines.html

  * igt@kms_busy@basic@flip:
    - {bat-adlp-6}:       [DMESG-WARN][20] ([i915#3576]) -> [PASS][21]
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/bat-adlp-6/igt@kms_busy@basic@flip.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/bat-adlp-6/igt@kms_busy@basic@flip.html

  * igt@kms_flip@basic-flip-vs-modeset@a-edp1:
    - fi-tgl-u2:          [DMESG-WARN][22] ([i915#402]) -> [PASS][23]
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11758/fi-tgl-u2/igt@kms_flip@basic-flip-vs-modeset@a-edp1.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/fi-tgl-u2/igt@kms_flip@basic-flip-vs-modeset@a-edp1.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1155]: https://gitlab.freedesktop.org/drm/intel/issues/1155
  [i915#2373]: https://gitlab.freedesktop.org/drm/intel/issues/2373
  [i915#2940]: https://gitlab.freedesktop.org/drm/intel/issues/2940
  [i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3576]: https://gitlab.freedesktop.org/drm/intel/issues/3576
  [i915#3595]: https://gitlab.freedesktop.org/drm/intel/issues/3595
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4418]: https://gitlab.freedesktop.org/drm/intel/issues/4418
  [i915#4494]: https://gitlab.freedesktop.org/drm/intel/issues/4494
  [i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
  [i915#4873]: https://gitlab.freedesktop.org/drm/intel/issues/4873
  [i915#4957]: https://gitlab.freedesktop.org/drm/intel/issues/4957
  [i915#5122]: https://gitlab.freedesktop.org/drm/intel/issues/5122
  [i915#5174]: https://gitlab.freedesktop.org/drm/intel/issues/5174
  [i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
  [i915#5274]: https://gitlab.freedesktop.org/drm/intel/issues/5274
  [i915#5594]: https://gitlab.freedesktop.org/drm/intel/issues/5594
  [i915#5716]: https://gitlab.freedesktop.org/drm/intel/issues/5716
  [i915#5763]: https://gitlab.freedesktop.org/drm/intel/issues/5763
  [i915#5885]: https://gitlab.freedesktop.org/drm/intel/issues/5885
  [i915#6011]: https://gitlab.freedesktop.org/drm/intel/issues/6011
  [i915#6227]: https://gitlab.freedesktop.org/drm/intel/issues/6227


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_6526 -> IGTPW_7311

  CI-20190529: 20190529
  CI_DRM_11758: a2644b16f1f05a1a6eff99d7076bfa0e770bdeb6 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_7311: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/index.html
  IGT_6526: 02888400228efbb29437726aa04114575ea939c3 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7311/index.html

[-- Attachment #2: Type: text/html, Size: 7991 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser
  2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
                   ` (23 preceding siblings ...)
  2022-06-15  0:24 ` [igt-dev] ✗ Fi.CI.BAT: failure for tools/intel_vbt_decode: Improve the parser Patchwork
@ 2022-06-15  6:44 ` Jani Nikula
  2022-06-15  8:19   ` Petri Latvala
  24 siblings, 1 reply; 28+ messages in thread
From: Jani Nikula @ 2022-06-15  6:44 UTC (permalink / raw)
  To: Ville Syrjala, igt-dev; +Cc: Latvala, Petri

On Wed, 15 Jun 2022, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Change the igt VBT parser to make copies of the BDB data blocks
> (just as we do in the kernel parser now). This makes it less
> hazardous/confusing if your block definition don't happent to
> match reality. 
>
> Eg. with the current scheme we could very easily misinterpret
> random bits from other blocks/etc. as our block data by just
> using an overly large structure for decoding. With the block
> copies being  at least as big as out struct definitions the
> worst that can happen is that we just decode some extra zeroes
> rather than some random other bits.
>
> The other thing I'm bringing over is the data pointer generation
> stuff for modern VBTS (which lack the LFP data table pointes block).
> That lets us keep decoding the LFP data block in exactly the
> same way on old and new VBTs.
>
> And naturally we have massive gaps in what data the tool actually
> parses from the VBT. So lots of patches to just parse more stuff.
> I didn't do an exhaustive study on this topic, so still probably
> missing some useful things.

I glanced through all this, and it LGTM, but can't claim I did a
detailed, thorough review. I also don't think it should really be
necessary for this particular tool. If the changes work for you, it's
good enough for me.

Cc: Petri, good to go with that?

BR,
Jani.

>
> Ville Syrjälä (23):
>   tools/intel_vbt_decode: update vbt defs from kernel
>   tools/intel_vbt_decode: Decode more DVO ports
>   tools/intel_vbt_decode: Decode mode HDMI data rates
>   tools/intel_vbt_decode: Clean up SSC freq decoding
>   tools/intel_vbt_decode: Decode DP max link rate
>   tools/intel_vbt_decode: Unify panel type handling
>   tools/intel_vbt_decode: Dump the block size
>   tools/intel_vbt_decode: Decode the LFP power block
>   tools/intel_vbt_decode: Dump the LVDS panel options
>   tools/intel_vbt_decode: Decode new fast link training rate
>   tools/intel_vbt_decode: Parse the old fast link training rate
>     correctly
>   tools/intel_vbt_decode: Parse the new eDP max link rate
>   tools/intel_vbt_decode: Include BDB block header in hex dump
>   tools/intel_vbt_decode: Make copies of the BDB blocks
>   tools/intel_vbt_decode: Specify a minimum size for the BDB block copy
>   tools/intel_vbt_decode: Convert LFP data pointers to be relative to
>     the data block
>   tools/intel_vbt_decode: Simplify LVDS data block parsing
>   tools/intel_vbt_decode: Dump the panel PNP ID
>   tools/intel_vbt_decode: Decode the end of the LFP data
>   tools/intel_vbt_decode: Dump the LVDS data ptrs
>   tools/intel_vbt_decode: Validate LVDS data table pointers
>   tools/intel_vbt_decode: Generate LVDS data table pointes if not
>     provided
>   tools/intel_vbt_decode: Warn if we lack the full definiton of the BDB
>     block
>
>  tools/intel_vbt_decode.c | 919 ++++++++++++++++++++++++++++++++++-----
>  tools/intel_vbt_defs.h   | 254 ++++++++---
>  2 files changed, 1018 insertions(+), 155 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser
  2022-06-15  6:44 ` [igt-dev] [PATCH i-g-t 00/23] " Jani Nikula
@ 2022-06-15  8:19   ` Petri Latvala
  2022-06-22 11:01     ` Jani Nikula
  0 siblings, 1 reply; 28+ messages in thread
From: Petri Latvala @ 2022-06-15  8:19 UTC (permalink / raw)
  To: Jani Nikula; +Cc: igt-dev

On Wed, Jun 15, 2022 at 09:44:26AM +0300, Jani Nikula wrote:
> On Wed, 15 Jun 2022, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > Change the igt VBT parser to make copies of the BDB data blocks
> > (just as we do in the kernel parser now). This makes it less
> > hazardous/confusing if your block definition don't happent to
> > match reality. 
> >
> > Eg. with the current scheme we could very easily misinterpret
> > random bits from other blocks/etc. as our block data by just
> > using an overly large structure for decoding. With the block
> > copies being  at least as big as out struct definitions the
> > worst that can happen is that we just decode some extra zeroes
> > rather than some random other bits.
> >
> > The other thing I'm bringing over is the data pointer generation
> > stuff for modern VBTS (which lack the LFP data table pointes block).
> > That lets us keep decoding the LFP data block in exactly the
> > same way on old and new VBTs.
> >
> > And naturally we have massive gaps in what data the tool actually
> > parses from the VBT. So lots of patches to just parse more stuff.
> > I didn't do an exhaustive study on this topic, so still probably
> > missing some useful things.
> 
> I glanced through all this, and it LGTM, but can't claim I did a
> detailed, thorough review. I also don't think it should really be
> necessary for this particular tool. If the changes work for you, it's
> good enough for me.
> 
> Cc: Petri, good to go with that?

Yeah, ack.


-- 
Petri Latvala

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser
  2022-06-15  8:19   ` Petri Latvala
@ 2022-06-22 11:01     ` Jani Nikula
  0 siblings, 0 replies; 28+ messages in thread
From: Jani Nikula @ 2022-06-22 11:01 UTC (permalink / raw)
  To: Petri Latvala; +Cc: igt-dev

On Wed, 15 Jun 2022, Petri Latvala <petri.latvala@intel.com> wrote:
> On Wed, Jun 15, 2022 at 09:44:26AM +0300, Jani Nikula wrote:
>> On Wed, 15 Jun 2022, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
>> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> >
>> > Change the igt VBT parser to make copies of the BDB data blocks
>> > (just as we do in the kernel parser now). This makes it less
>> > hazardous/confusing if your block definition don't happent to
>> > match reality. 
>> >
>> > Eg. with the current scheme we could very easily misinterpret
>> > random bits from other blocks/etc. as our block data by just
>> > using an overly large structure for decoding. With the block
>> > copies being  at least as big as out struct definitions the
>> > worst that can happen is that we just decode some extra zeroes
>> > rather than some random other bits.
>> >
>> > The other thing I'm bringing over is the data pointer generation
>> > stuff for modern VBTS (which lack the LFP data table pointes block).
>> > That lets us keep decoding the LFP data block in exactly the
>> > same way on old and new VBTs.
>> >
>> > And naturally we have massive gaps in what data the tool actually
>> > parses from the VBT. So lots of patches to just parse more stuff.
>> > I didn't do an exhaustive study on this topic, so still probably
>> > missing some useful things.
>> 
>> I glanced through all this, and it LGTM, but can't claim I did a
>> detailed, thorough review. I also don't think it should really be
>> necessary for this particular tool. If the changes work for you, it's
>> good enough for me.
>> 
>> Cc: Petri, good to go with that?
>
> Yeah, ack.

Ville, I think you can just merge.

You can put

Reviewed-by: Jani Nikula <jani.nikula@intel.com>

on it, but with the caveat above.

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2022-06-22 11:01 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-14 23:30 [igt-dev] [PATCH i-g-t 00/23] tools/intel_vbt_decode: Improve the parser Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 01/23] tools/intel_vbt_decode: update vbt defs from kernel Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 02/23] tools/intel_vbt_decode: Decode more DVO ports Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 03/23] tools/intel_vbt_decode: Decode mode HDMI data rates Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 04/23] tools/intel_vbt_decode: Clean up SSC freq decoding Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 05/23] tools/intel_vbt_decode: Decode DP max link rate Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 06/23] tools/intel_vbt_decode: Unify panel type handling Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 07/23] tools/intel_vbt_decode: Dump the block size Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 08/23] tools/intel_vbt_decode: Decode the LFP power block Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 09/23] tools/intel_vbt_decode: Dump the LVDS panel options Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 10/23] tools/intel_vbt_decode: Decode new fast link training rate Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 11/23] tools/intel_vbt_decode: Parse the old fast link training rate correctly Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 12/23] tools/intel_vbt_decode: Parse the new eDP max link rate Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 13/23] tools/intel_vbt_decode: Include BDB block header in hex dump Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 14/23] tools/intel_vbt_decode: Make copies of the BDB blocks Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 15/23] tools/intel_vbt_decode: Specify a minimum size for the BDB block copy Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 16/23] tools/intel_vbt_decode: Convert LFP data pointers to be relative to the data block Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 17/23] tools/intel_vbt_decode: Simplify LVDS data block parsing Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 18/23] tools/intel_vbt_decode: Dump the panel PNP ID Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 19/23] tools/intel_vbt_decode: Decode the end of the LFP data Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 20/23] tools/intel_vbt_decode: Dump the LVDS data ptrs Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 21/23] tools/intel_vbt_decode: Validate LVDS data table pointers Ville Syrjala
2022-06-14 23:30 ` [igt-dev] [PATCH i-g-t 22/23] tools/intel_vbt_decode: Generate LVDS data table pointes if not provided Ville Syrjala
2022-06-14 23:31 ` [igt-dev] [PATCH i-g-t 23/23] tools/intel_vbt_decode: Warn if we lack the full definiton of the BDB block Ville Syrjala
2022-06-15  0:24 ` [igt-dev] ✗ Fi.CI.BAT: failure for tools/intel_vbt_decode: Improve the parser Patchwork
2022-06-15  6:44 ` [igt-dev] [PATCH i-g-t 00/23] " Jani Nikula
2022-06-15  8:19   ` Petri Latvala
2022-06-22 11:01     ` Jani Nikula

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.