mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-03 08:50:17 -04:00
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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user