diff options
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics/Kconfig | 3 | ||||
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics/Makefile.inc | 15 | ||||
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics/chip.h | 54 | ||||
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics/hybrid_graphics.c | 72 | ||||
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics/hybrid_graphics.h | 21 | ||||
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics/romstage.c | 95 |
6 files changed, 260 insertions, 0 deletions
diff --git a/src/drivers/lenovo/hybrid_graphics/Kconfig b/src/drivers/lenovo/hybrid_graphics/Kconfig new file mode 100644 index 0000000000..389dfb919f --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics/Kconfig @@ -0,0 +1,3 @@ +config DRIVERS_LENOVO_HYBRID_GRAPHICS + bool + default n diff --git a/src/drivers/lenovo/hybrid_graphics/Makefile.inc b/src/drivers/lenovo/hybrid_graphics/Makefile.inc new file mode 100644 index 0000000000..d9e50797c3 --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics/Makefile.inc @@ -0,0 +1,15 @@ +# +# This file is part of the coreboot project. +# +# 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 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. +# + +ramstage-$(CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS) += hybrid_graphics.c +romstage-$(CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS) += romstage.c diff --git a/src/drivers/lenovo/hybrid_graphics/chip.h b/src/drivers/lenovo/hybrid_graphics/chip.h new file mode 100644 index 0000000000..96d7f9c1a9 --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics/chip.h @@ -0,0 +1,54 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org> + * + * 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 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. + */ + +#ifndef _LENOVO_HYBRID_GRAPHICS_CHIP_H_ +#define _LENOVO_HYBRID_GRAPHICS_CHIP_H_ + +#define HYBRID_GRAPHICS_PORT 0xff + +#define HYBRID_GRAPHICS_DEVICE 0xf + +enum hybrid_graphics_req { + HYBRID_GRAPHICS_INTEGRATED = 0, + HYBRID_GRAPHICS_DISCRETE = 1, + HYBRID_GRAPHICS_DUAL = 2 +}; + +enum dgpu_detect_lvl { + DGPU_INSTALLED = 0, + DGPU_NOT_INSTALLED = 1, +}; + +#define HYBRID_GRAPHICS_DEFAULT_GPU HYBRID_GRAPHICS_INTEGRATED + +struct drivers_lenovo_hybrid_graphics_config { + unsigned int detect_gpio; + + unsigned int has_panel_hybrid_gpio; + unsigned int panel_hybrid_gpio; + unsigned int panel_integrated_lvl; + + unsigned int has_backlight_gpio; + unsigned int backlight_gpio; + unsigned int backlight_integrated_lvl; + + unsigned int has_dgpu_power_gpio; + unsigned int dgpu_power_gpio; + unsigned int dgpu_power_off_lvl; + + unsigned int has_thinker1; +}; + +#endif /* _LENOVO_HYBRID_GRAPHICS_CHIP_H_ */ diff --git a/src/drivers/lenovo/hybrid_graphics/hybrid_graphics.c b/src/drivers/lenovo/hybrid_graphics/hybrid_graphics.c new file mode 100644 index 0000000000..4fa5b81e8e --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics/hybrid_graphics.c @@ -0,0 +1,72 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org> + * + * 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 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. + */ + +#include <types.h> +#include <option.h> +#include <device/device.h> + +#include <southbridge/intel/common/gpio.h> +#include <console/console.h> +#include "chip.h" + +/* + * Switch panel mux or backlight mux to active GPU. + * In case both GPUs are active switch panel mux to integrated. + */ +static void lenovo_hybrid_graphics_enable(struct device *dev) +{ + const struct drivers_lenovo_hybrid_graphics_config *config; + enum hybrid_graphics_req mode = HYBRID_GRAPHICS_DEFAULT_GPU; + + /* Don't confuse anyone else and disable the fake device */ + dev->enabled = 0; + + config = dev->chip_info; + if (!config || (get_gpio(config->detect_gpio) == DGPU_NOT_INSTALLED)) { + printk(BIOS_DEBUG, "Hybrid graphics: Not installed\n"); + return; + } + + get_option(&mode, "hybrid_graphics_mode"); + + if (mode == HYBRID_GRAPHICS_DISCRETE) { + printk(BIOS_DEBUG, "Hybrid graphics:" + " Switching panel to discrete GPU.\n"); + + if (config->has_panel_hybrid_gpio) + set_gpio(config->panel_hybrid_gpio, + !config->panel_integrated_lvl); + + if (config->has_backlight_gpio) + set_gpio(config->backlight_gpio, + !config->backlight_integrated_lvl); + } else { + printk(BIOS_DEBUG, "Hybrid graphics:" + " Switching panel to integrated GPU.\n"); + + if (config->has_panel_hybrid_gpio) + set_gpio(config->panel_hybrid_gpio, + config->panel_integrated_lvl); + + if (config->has_backlight_gpio) + set_gpio(config->backlight_gpio, + config->backlight_integrated_lvl); + } +} + +struct chip_operations drivers_lenovo_hybrid_graphics_ops = { + CHIP_NAME("Lenovo hybrid graphics driver") + .enable_dev = &lenovo_hybrid_graphics_enable +}; diff --git a/src/drivers/lenovo/hybrid_graphics/hybrid_graphics.h b/src/drivers/lenovo/hybrid_graphics/hybrid_graphics.h new file mode 100644 index 0000000000..b238440caa --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics/hybrid_graphics.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org> + * + * 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 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. + */ + +#ifndef _DRIVERS_LENOVO_HYBRID_GRAPHICS_H_ +#define _DRIVERS_LENOVO_HYBRID_GRAPHICS_H_ + +void early_hybrid_graphics(bool *enable_igd, bool *enable_peg); + +#endif /* _DRIVERS_LENOVO_HYBRID_GRAPHICS_CHIP_H_ */ diff --git a/src/drivers/lenovo/hybrid_graphics/romstage.c b/src/drivers/lenovo/hybrid_graphics/romstage.c new file mode 100644 index 0000000000..9009c5841a --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics/romstage.c @@ -0,0 +1,95 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org> + * + * 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 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. + */ + +#include <types.h> +#include <option.h> +#include <device/device.h> + +#include <southbridge/intel/common/gpio.h> +#include <ec/lenovo/pmh7/pmh7.h> +#include <console/console.h> +#include <delay.h> + +#include "hybrid_graphics.h" +#include "chip.h" + +/* + * Returns the hybrid graphics presence and user's card preferences. + */ +void early_hybrid_graphics(bool *enable_igd, bool *enable_peg) +{ + const struct drivers_lenovo_hybrid_graphics_config *config; + const struct device *dev; + enum hybrid_graphics_req mode = HYBRID_GRAPHICS_DEFAULT_GPU; + + /* TODO: Use generic device instead of dummy PNP device */ + dev = dev_find_slot_pnp(HYBRID_GRAPHICS_PORT, HYBRID_GRAPHICS_DEVICE); + + if (!dev || !dev->chip_info) { + printk(BIOS_ERR, "Hybrid graphics: ERROR\n"); + *enable_igd = true; + *enable_peg = false; + return; + } + + config = dev->chip_info; + if (get_gpio(config->detect_gpio) == DGPU_NOT_INSTALLED) { + printk(BIOS_DEBUG, "Hybrid graphics:" + " No discrete GPU present.\n"); + *enable_igd = true; + *enable_peg = false; + return; + } + + get_option(&mode, "hybrid_graphics_mode"); + + if (mode == HYBRID_GRAPHICS_DISCRETE) { + printk(BIOS_DEBUG, "Hybrid graphics:" + " Disabling integrated GPU.\n"); + + *enable_igd = false; + *enable_peg = true; + } else if (mode == HYBRID_GRAPHICS_INTEGRATED) { + printk(BIOS_DEBUG, "Hybrid graphics:" + " Disabling discrete GPU.\n"); + + *enable_igd = true; + *enable_peg = false; + } else { + printk(BIOS_DEBUG, "Hybrid graphics:" + " Activating Switchable (both GPUs).\n"); + + *enable_igd = true; + *enable_peg = true; + } + + /* + * Need to do power handling here as we know there's a dGPU to + * turn off. Support GPIO and Thinker1. + */ + if (!*enable_peg) { + if (config->has_dgpu_power_gpio) { + set_gpio(config->dgpu_power_gpio, + config->dgpu_power_off_lvl); + } else if (config->has_thinker1) { + pmh7_register_clear_bit(0x50, 7); // DGPU_RST + udelay(100); + pmh7_register_clear_bit(0x50, 3); // DGPU_PWR + } else { + printk(BIOS_ERR, "Hybrid graphics:" + " FIXME: dGPU power not disabled !\n"); + } + } +} |