summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2022-05-04 18:04:34 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2022-05-05 18:25:23 +0300
commit901a0cad2ab8f6edcb3f21f88037eab54c48fd1a (patch)
treecb713d19391a7aab27fa028f993805a99d437d9f
parenta87d0a84760726445dcc0f0177623f0d683f3559 (diff)
downloadlinux-901a0cad2ab8f6edcb3f21f88037eab54c48fd1a.tar.bz2
drm/i915/bios: Get access to the tail end of the LFP data block
We need to start parsing stuff from the tail end of the LFP data block. This is made awkward by the fact that the fp_timing table has variable size. So we must use a bit more finesse to get the tail end, and to make sure we allocate enough memory for it to make sure our struct representation fits. v2: Rebase due to the preallocation of BDB blocks v3: Rebase due to min_size WARN relocation v4: Document BDB_LVDS_LFP_DATA vs. BDB_LVDS_LFP_DATA_PTRS order (Jani) Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220504150440.13748-4-ville.syrjala@linux.intel.com
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c43
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h17
2 files changed, 59 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 4cea9c27b198..4d7953e74814 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -185,10 +185,14 @@ static const struct {
.min_size = sizeof(struct bdb_edp), },
{ .section_id = BDB_LVDS_OPTIONS,
.min_size = sizeof(struct bdb_lvds_options), },
+ /*
+ * BDB_LVDS_LFP_DATA depends on BDB_LVDS_LFP_DATA_PTRS,
+ * so keep the two ordered.
+ */
{ .section_id = BDB_LVDS_LFP_DATA_PTRS,
.min_size = sizeof(struct bdb_lvds_lfp_data_ptrs), },
{ .section_id = BDB_LVDS_LFP_DATA,
- .min_size = sizeof(struct bdb_lvds_lfp_data), },
+ .min_size = 0, /* special case */ },
{ .section_id = BDB_LVDS_BACKLIGHT,
.min_size = sizeof(struct bdb_lfp_backlight_data), },
{ .section_id = BDB_LFP_POWER,
@@ -203,6 +207,23 @@ static const struct {
.min_size = sizeof(struct bdb_generic_dtd), },
};
+static size_t lfp_data_min_size(struct drm_i915_private *i915)
+{
+ const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ size_t size;
+
+ ptrs = find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ if (!ptrs)
+ return 0;
+
+ 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));
+
+ return size;
+}
+
static bool validate_lfp_data_ptrs(const void *bdb,
const struct bdb_lvds_lfp_data_ptrs *ptrs)
{
@@ -490,6 +511,9 @@ static void init_bdb_blocks(struct drm_i915_private *i915,
enum bdb_block_id section_id = bdb_blocks[i].section_id;
size_t min_size = bdb_blocks[i].min_size;
+ if (section_id == BDB_LVDS_LFP_DATA)
+ min_size = lfp_data_min_size(i915);
+
init_bdb_block(i915, bdb, section_id, min_size);
}
}
@@ -560,6 +584,16 @@ get_lvds_fp_timing(const struct bdb_lvds_lfp_data *data,
return (const void *)data + ptrs->ptr[index].fp_timing.offset;
}
+static const struct bdb_lvds_lfp_data_tail *
+get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
+ const struct bdb_lvds_lfp_data_ptrs *ptrs)
+{
+ if (ptrs->panel_name.table_size)
+ return (const void *)data + ptrs->panel_name.offset;
+ else
+ return NULL;
+}
+
/* Parse general panel options */
static void
parse_panel_options(struct drm_i915_private *i915)
@@ -664,6 +698,7 @@ static void
parse_lfp_data(struct drm_i915_private *i915)
{
const struct bdb_lvds_lfp_data *data;
+ const struct bdb_lvds_lfp_data_tail *tail;
const struct bdb_lvds_lfp_data_ptrs *ptrs;
ptrs = find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
@@ -676,6 +711,12 @@ parse_lfp_data(struct drm_i915_private *i915)
if (!i915->vbt.lfp_lvds_vbt_mode)
parse_lfp_panel_dtd(i915, data, ptrs);
+
+ tail = get_lfp_data_tail(data, ptrs);
+ if (!tail)
+ return;
+
+ (void)tail;
}
static void
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index e4a11c3e3f3e..2554f4b9b4da 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -783,6 +783,23 @@ 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
*/