diff options
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/intel/gma/Makefile.inc | 2 | ||||
-rw-r--r-- | src/drivers/intel/gma/i915.h | 19 | ||||
-rw-r--r-- | src/drivers/intel/gma/intel_bios.h | 52 | ||||
-rw-r--r-- | src/drivers/intel/gma/vbt.c | 110 |
4 files changed, 182 insertions, 1 deletions
diff --git a/src/drivers/intel/gma/Makefile.inc b/src/drivers/intel/gma/Makefile.inc index b19334eef6..d963df9abb 100644 --- a/src/drivers/intel/gma/Makefile.inc +++ b/src/drivers/intel/gma/Makefile.inc @@ -19,7 +19,7 @@ ramstage-$(CONFIG_INTEL_DP) += intel_dp.c drm_dp_helper.c display.c ramstage-$(CONFIG_INTEL_DDI) += intel_ddi.c -ramstage-$(CONFIG_INTEL_EDID) += edid.c +ramstage-$(CONFIG_INTEL_EDID) += edid.c vbt.c ifeq ($(CONFIG_VGA_ROM_RUN),y) ramstage-$(CONFIG_INTEL_INT15) += int15.c endif diff --git a/src/drivers/intel/gma/i915.h b/src/drivers/intel/gma/i915.h index bc43fc5ec0..0d5b8af8ef 100644 --- a/src/drivers/intel/gma/i915.h +++ b/src/drivers/intel/gma/i915.h @@ -17,6 +17,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef INTEL_I915_H +#define INTEL_I915_H 1 + #include <drivers/intel/gma/i915_reg.h> #include <drivers/intel/gma/drm_dp_helper.h> #include <edid.h> @@ -282,6 +285,14 @@ int gtt_poll(u32 reg, u32 mask, u32 value); void gtt_write(u32 reg, u32 data); u32 gtt_read(u32 reg); +struct i915_gpu_controller_info +{ + int use_spread_spectrum_clock; + int lvds_dual_channel; + int link_frequency_270_mhz; + int lvds_num_lanes; +}; + int i915lightup(unsigned int physbase, unsigned int mmio, unsigned int gfx, unsigned int init_fb); int panel_lightup(struct intel_dp *dp, unsigned int init_fb); @@ -289,3 +300,11 @@ void *igd_make_opregion(void); /* display.c */ void compute_display_params(struct intel_dp *dp); + +/* vbt.c */ +struct device; +void +generate_fake_intel_oprom(const struct i915_gpu_controller_info *conf, + struct device *dev, const char *idstr); + +#endif diff --git a/src/drivers/intel/gma/intel_bios.h b/src/drivers/intel/gma/intel_bios.h index 36426d81f9..7b5edd3f39 100644 --- a/src/drivers/intel/gma/intel_bios.h +++ b/src/drivers/intel/gma/intel_bios.h @@ -730,4 +730,56 @@ struct bdb_mipi { u32 clk_lane_switch_cnt; } __attribute__((packed)); +/* Intel Video BIOS (Option ROM) */ +typedef struct { + u16 signature; + u8 size; + u8 reserved[21]; + u16 pcir_offset; + u16 vbt_offset; +} __attribute__((packed)) optionrom_header_t; + +#define OPROM_SIGNATURE 0xaa55 + +typedef struct { + u32 signature; + u16 vendor; + u16 device; + u16 reserved1; + u16 length; + u8 revision; + u8 classcode[3]; + u16 imagelength; + u16 coderevision; + u8 codetype; + u8 indicator; + u16 reserved2; +} __attribute__((packed)) optionrom_pcir_t; + +typedef struct { + u8 hdr_signature[20]; + u16 hdr_version; + u16 hdr_size; + u16 hdr_vbt_size; + u8 hdr_vbt_checksum; + u8 hdr_reserved; + u32 hdr_vbt_datablock; + u32 hdr_aim[4]; + u8 datahdr_signature[16]; + u16 datahdr_version; + u16 datahdr_size; + u16 datahdr_datablocksize; + u8 coreblock_id; + u16 coreblock_size; + u16 coreblock_biossize; + u8 coreblock_biostype; + u8 coreblock_releasestatus; + u8 coreblock_hwsupported; + u8 coreblock_integratedhw; + u8 coreblock_biosbuild[4]; + u8 coreblock_biossignon[155]; +} __attribute__((packed)) optionrom_vbt_t; + +#define VBT_SIGNATURE 0x54425624 + #endif /* _I830_BIOS_H_ */ diff --git a/src/drivers/intel/gma/vbt.c b/src/drivers/intel/gma/vbt.c new file mode 100644 index 0000000000..1cc4e93ae6 --- /dev/null +++ b/src/drivers/intel/gma/vbt.c @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013, 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 or (at your option) + * any later version of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arch/io.h> +#include <console/console.h> +#include <delay.h> +#include <device/device.h> +#include <string.h> +#include <device/pci_rom.h> + +#include "i915.h" +#include "intel_bios.h" + +static size_t generate_vbt(const struct i915_gpu_controller_info *conf, + void *vbt, const char *idstr) +{ + struct vbt_header *head = vbt; + struct bdb_header *bdb_head; + struct bdb_general_features *genfeat; + u8 *ptr; + + memset (head, 0, sizeof (*head)); + + memcpy (head->signature, idstr, 20); + head->version = 100; + head->header_size = sizeof (*head); + head->bdb_offset = sizeof (*head); + + bdb_head = (struct bdb_header *) (head + 1); + memset (bdb_head, 0, sizeof (*bdb_head)); + memcpy (bdb_head->signature, "BIOS_DATA_BLOCK ", 16); + bdb_head->version = 0xa8; + bdb_head->header_size = sizeof (*bdb_head); + + ptr = (u8 *) (bdb_head + 1); + + ptr[0] = BDB_GENERAL_FEATURES; + ptr[1] = sizeof (*genfeat); + ptr[2] = sizeof (*genfeat) >> 8; + ptr += 3; + + genfeat = (struct bdb_general_features *) ptr; + memset (genfeat, 0, sizeof (*genfeat)); + genfeat->panel_fitting = 3; + genfeat->flexaim = 1; + genfeat->download_ext_vbt = 1; + genfeat->enable_ssc = conf->use_spread_spectrum_clock; + genfeat->ssc_freq = !conf->link_frequency_270_mhz; + genfeat->rsvd10 = 0x4; + genfeat->legacy_monitor_detect = 1; + genfeat->int_crt_support = 1; + genfeat->dp_ssc_enb = 1; + + ptr += sizeof (*genfeat); + + bdb_head->bdb_size = ptr - (u8 *)bdb_head; + head->vbt_size = ptr - (u8 *)head; + head->vbt_checksum = 0; + return ptr - (u8 *)head; +} + +void +generate_fake_intel_oprom(const struct i915_gpu_controller_info *conf, + struct device *dev, const char *idstr) +{ + optionrom_header_t *oh = (void *)PCI_VGA_RAM_IMAGE_START; + optionrom_pcir_t *pcir; + size_t vbt_size; + size_t fake_oprom_size; + + memset(oh, 0, 8192); + + oh->signature = PCI_ROM_HDR; + oh->pcir_offset = 0x40; + oh->vbt_offset = 0x80; + + pcir = (void *)(PCI_VGA_RAM_IMAGE_START + 0x40); + pcir->signature = 0x52494350; // PCIR + pcir->vendor = dev->vendor; + pcir->device = dev->device; + pcir->length = sizeof(*pcir); + pcir->revision = dev->class; + pcir->classcode[0] = dev->class >> 8; + pcir->classcode[1] = dev->class >> 16; + pcir->classcode[2] = dev->class >> 24; + pcir->indicator = 0x80; + + vbt_size = generate_vbt (conf, (void *)(PCI_VGA_RAM_IMAGE_START + 0x80), idstr); + fake_oprom_size = (0x80 + vbt_size + 511) / 512; + oh->size = fake_oprom_size; + pcir->imagelength = fake_oprom_size; + +} |