blob: 9009c5841a65bea2c9d84b6b34743dfe53ad806a [file] [log] [blame]
Patrick Rudolphd7dcc442017-07-25 17:40:36 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <types.h>
17#include <option.h>
18#include <device/device.h>
19
20#include <southbridge/intel/common/gpio.h>
21#include <ec/lenovo/pmh7/pmh7.h>
22#include <console/console.h>
23#include <delay.h>
24
25#include "hybrid_graphics.h"
26#include "chip.h"
27
28/*
29 * Returns the hybrid graphics presence and user's card preferences.
30 */
31void early_hybrid_graphics(bool *enable_igd, bool *enable_peg)
32{
33 const struct drivers_lenovo_hybrid_graphics_config *config;
34 const struct device *dev;
35 enum hybrid_graphics_req mode = HYBRID_GRAPHICS_DEFAULT_GPU;
36
37 /* TODO: Use generic device instead of dummy PNP device */
38 dev = dev_find_slot_pnp(HYBRID_GRAPHICS_PORT, HYBRID_GRAPHICS_DEVICE);
39
40 if (!dev || !dev->chip_info) {
41 printk(BIOS_ERR, "Hybrid graphics: ERROR\n");
42 *enable_igd = true;
43 *enable_peg = false;
44 return;
45 }
46
47 config = dev->chip_info;
48 if (get_gpio(config->detect_gpio) == DGPU_NOT_INSTALLED) {
49 printk(BIOS_DEBUG, "Hybrid graphics:"
50 " No discrete GPU present.\n");
51 *enable_igd = true;
52 *enable_peg = false;
53 return;
54 }
55
56 get_option(&mode, "hybrid_graphics_mode");
57
58 if (mode == HYBRID_GRAPHICS_DISCRETE) {
59 printk(BIOS_DEBUG, "Hybrid graphics:"
60 " Disabling integrated GPU.\n");
61
62 *enable_igd = false;
63 *enable_peg = true;
64 } else if (mode == HYBRID_GRAPHICS_INTEGRATED) {
65 printk(BIOS_DEBUG, "Hybrid graphics:"
66 " Disabling discrete GPU.\n");
67
68 *enable_igd = true;
69 *enable_peg = false;
70 } else {
71 printk(BIOS_DEBUG, "Hybrid graphics:"
72 " Activating Switchable (both GPUs).\n");
73
74 *enable_igd = true;
75 *enable_peg = true;
76 }
77
78 /*
79 * Need to do power handling here as we know there's a dGPU to
80 * turn off. Support GPIO and Thinker1.
81 */
82 if (!*enable_peg) {
83 if (config->has_dgpu_power_gpio) {
84 set_gpio(config->dgpu_power_gpio,
85 config->dgpu_power_off_lvl);
86 } else if (config->has_thinker1) {
87 pmh7_register_clear_bit(0x50, 7); // DGPU_RST
88 udelay(100);
89 pmh7_register_clear_bit(0x50, 3); // DGPU_PWR
90 } else {
91 printk(BIOS_ERR, "Hybrid graphics:"
92 " FIXME: dGPU power not disabled !\n");
93 }
94 }
95}