1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/pci_ops.h>
4 #include <device/device.h>
6 #include <device/pci.h>
7 #include <drivers/intel/gma/opregion.h>
10 #include "intel_bios.h"
12 static size_t generate_vbt(const struct i915_gpu_controller_info
*const conf
,
13 struct vbt_header
*const head
,
14 const char *const idstr
)
18 memset(head
, 0, sizeof(*head
));
20 memset(head
->signature
, ' ', sizeof(head
->signature
));
21 memcpy(head
->signature
, idstr
,
22 MIN(strlen(idstr
), sizeof(head
->signature
)));
24 head
->header_size
= sizeof(*head
);
25 head
->bdb_offset
= sizeof(*head
);
27 struct bdb_header
*const bdb_head
= (struct bdb_header
*)(head
+ 1);
28 memset(bdb_head
, 0, sizeof(*bdb_head
));
29 memcpy(bdb_head
->signature
, "BIOS_DATA_BLOCK ", 16);
30 bdb_head
->version
= 0xa8;
31 bdb_head
->header_size
= sizeof(*bdb_head
);
33 ptr
= (u8
*)(bdb_head
+ 1);
35 ptr
[0] = BDB_GENERAL_FEATURES
;
36 ptr
[1] = sizeof(struct bdb_general_features
);
37 ptr
[2] = sizeof(struct bdb_general_features
) >> 8;
40 struct bdb_general_features
*const genfeat
=
41 (struct bdb_general_features
*)ptr
;
42 memset(genfeat
, 0, sizeof(*genfeat
));
43 genfeat
->panel_fitting
= 3;
45 genfeat
->download_ext_vbt
= 1;
46 genfeat
->enable_ssc
= conf
->use_spread_spectrum_clock
;
47 genfeat
->ssc_freq
= CONFIG(INTEL_GMA_SSC_ALTERNATE_REF
);
48 genfeat
->rsvd10
= 0x4;
49 genfeat
->legacy_monitor_detect
= 1;
50 genfeat
->int_crt_support
= 1;
51 genfeat
->dp_ssc_enb
= 1;
53 ptr
+= sizeof(*genfeat
);
55 bdb_head
->bdb_size
= ptr
- (u8
*)bdb_head
;
56 head
->vbt_size
= ptr
- (u8
*)head
;
57 head
->vbt_checksum
= 0;
58 return ptr
- (u8
*)head
;
62 generate_fake_intel_oprom(const struct i915_gpu_controller_info
*const conf
,
63 struct device
*const dev
, const char *const idstr
)
65 optionrom_header_t
*const oh
= (void *)PCI_VGA_RAM_IMAGE_START
;
69 oh
->signature
= PCI_ROM_HDR
;
70 oh
->pcir_offset
= 0x40;
71 oh
->vbt_offset
= 0x80;
73 optionrom_pcir_t
*const pcir
= (void *)((u8
*)oh
+ oh
->pcir_offset
);
74 pcir
->signature
= 0x52494350; // PCIR
75 pcir
->vendor
= dev
->vendor
;
76 pcir
->device
= dev
->device
;
77 pcir
->length
= sizeof(*pcir
);
78 pcir
->revision
= pci_read_config8(dev
, PCI_CLASS_REVISION
);
79 pcir
->classcode
[0] = dev
->class;
80 pcir
->classcode
[1] = dev
->class >> 8;
81 pcir
->classcode
[2] = dev
->class >> 16;
82 pcir
->indicator
= 0x80;
84 const size_t vbt_size
=
85 generate_vbt(conf
, (void *)((u8
*)oh
+ oh
->vbt_offset
), idstr
);
86 const size_t fake_oprom_size
=
87 DIV_ROUND_UP(oh
->vbt_offset
+ vbt_size
, 512);
88 oh
->size
= fake_oprom_size
;
89 pcir
->imagelength
= fake_oprom_size
;