return validate_lfp_data_ptrs(bdb, ptrs);
 }
 
-static const void *find_fp_timing_terminator(const u8 *data, int size)
-{
-       int i;
-
-       for (i = 0; i < size - 1; i++) {
-               if (data[i] == 0xff && data[i+1] == 0xff)
-                       return &data[i];
-       }
-
-       return NULL;
-}
-
 static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
                             int table_size, int total_size)
 {
 static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
                                    const void *bdb)
 {
-       int i, size, table_size, block_size, offset;
-       const void *t0, *t1, *block;
+       int i, size, table_size, block_size, offset, fp_timing_size;
        struct bdb_lvds_lfp_data_ptrs *ptrs;
+       const void *block;
        void *ptrs_block;
 
+       /*
+        * The hardcoded fp_timing_size is only valid for
+        * modernish VBTs. All older VBTs definitely should
+        * include block 41 and thus we don't need to
+        * generate one.
+        */
+       if (i915->display.vbt.version < 155)
+               return NULL;
+
+       fp_timing_size = 38;
+
        block = find_raw_section(bdb, 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;
+       size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
+               sizeof(struct lvds_pnp_id);
        if (size * 16 > block_size)
                return NULL;
 
        table_size = sizeof(struct lvds_dvo_timing);
        size = make_lfp_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
 
-       table_size = t0 - block + 2;
+       table_size = fp_timing_size;
        size = make_lfp_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
 
        if (ptrs->ptr[0].fp_timing.table_size)
                return NULL;
        }
 
-       size = t1 - t0;
+       size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
+               sizeof(struct lvds_pnp_id);
        for (i = 1; i < 16; i++) {
                next_lfp_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
                next_lfp_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
                next_lfp_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) {