blob: 8814916872132539dee9b941e0867a8f436d1295 [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 /*
Patrick Rudolphe07e3902017-11-04 20:13:22 +010079 * Need to do power handling here as we know there's a dGPU.
80 * Support GPIO and Thinker1.
Patrick Rudolphd7dcc442017-07-25 17:40:36 +020081 */
Patrick Rudolphe07e3902017-11-04 20:13:22 +010082 if (config->has_dgpu_power_gpio) {
83 if (*enable_peg)
84 set_gpio(config->dgpu_power_gpio,
85 !config->dgpu_power_off_lvl);
86 else
Patrick Rudolphd7dcc442017-07-25 17:40:36 +020087 set_gpio(config->dgpu_power_gpio,
88 config->dgpu_power_off_lvl);
Patrick Rudolphe07e3902017-11-04 20:13:22 +010089 } else if (config->has_thinker1) {
90 const size_t power_en = !!(pmh7_register_read(0x50) & 0x08);
91 if (*enable_peg && !power_en) {
92 pmh7_register_clear_bit(0x50, 7); // DGPU_RST
93 pmh7_register_set_bit(0x50, 3); // DGPU_PWR
94 mdelay(10);
95 pmh7_register_set_bit(0x50, 7); // DGPU_RST
96 mdelay(50);
97 } else if (!*enable_peg && power_en) {
Patrick Rudolphd7dcc442017-07-25 17:40:36 +020098 pmh7_register_clear_bit(0x50, 7); // DGPU_RST
99 udelay(100);
100 pmh7_register_clear_bit(0x50, 3); // DGPU_PWR
Patrick Rudolphd7dcc442017-07-25 17:40:36 +0200101 }
Patrick Rudolphe07e3902017-11-04 20:13:22 +0100102 } else {
103 printk(BIOS_ERR, "Hybrid graphics:"
104 " FIXME: dGPU power handling not implemented\n");
Patrick Rudolphd7dcc442017-07-25 17:40:36 +0200105 }
106}