blob: 9dd668fd7531ec30c93bb2aa9b443419e1d42888 [file] [log] [blame]
Uwe Hermann539500e2011-02-02 23:56:15 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 Sven Schnelle <svens@stackframe.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.
Uwe Hermann539500e2011-02-02 23:56:15 +000014 */
15
Sven Schnelle4a6c9d12011-02-01 10:44:26 +000016#include <arch/io.h>
17#include <console/console.h>
18#include <device/device.h>
19#include <device/pnp.h>
Edward O'Callaghanb57fef92014-06-17 20:13:08 +100020#include <pc80/mc146818rtc.h>
Evgeny Zinoviev384e9ae2018-08-30 02:18:48 +030021#include <delay.h>
Elyes HAOUAS5fd93e02019-05-15 21:07:30 +020022#include <types.h>
Edward O'Callaghanb57fef92014-06-17 20:13:08 +100023
Sven Schnelle4a6c9d12011-02-01 10:44:26 +000024#include "pmh7.h"
Sven Schnelle1fa61eb2011-04-11 19:43:50 +000025#include "chip.h"
26
27void pmh7_backlight_enable(int onoff)
28{
29 if (onoff)
30 pmh7_register_set_bit(0x50, 5);
31 else
32 pmh7_register_clear_bit(0x50, 5);
33}
Sven Schnelle4a6c9d12011-02-01 10:44:26 +000034
Sven Schnelle1b9d2ee2011-04-17 12:54:32 +000035void pmh7_dock_event_enable(int onoff)
36{
37 if (onoff)
38 pmh7_register_set_bit(0x60, 3);
39 else
40 pmh7_register_clear_bit(0x60, 3);
41
42}
Sven Schnelle4fff74b2011-04-19 19:57:26 +000043
44void pmh7_touchpad_enable(int onoff)
45{
46 if (onoff)
47 pmh7_register_clear_bit(0x51, 2);
48 else
49 pmh7_register_set_bit(0x51, 2);
50}
Sven Schnellebf9e9302011-04-27 19:47:42 +000051
Vladimir Serbinenkoeada34f2014-01-11 04:22:35 +010052void pmh7_trackpoint_enable(int onoff)
53{
54 if (onoff)
55 pmh7_register_clear_bit(0x51, 0);
56 else
57 pmh7_register_set_bit(0x51, 0);
58}
59
Sven Schnellebf9e9302011-04-27 19:47:42 +000060void pmh7_ultrabay_power_enable(int onoff)
61{
62 if (onoff)
63 pmh7_register_clear_bit(0x62, 0);
64 else
65 pmh7_register_set_bit(0x62, 0);
66}
67
Evgeny Zinoviev384e9ae2018-08-30 02:18:48 +030068void pmh7_dgpu_power_enable(int onoff)
69{
70 if (onoff) {
71 pmh7_register_clear_bit(0x50, 7); // DGPU_RST
72 pmh7_register_set_bit(0x50, 3); // DGPU_PWR
73 mdelay(10);
74 pmh7_register_set_bit(0x50, 7); // DGPU_RST
75 mdelay(50);
76 } else {
77 pmh7_register_clear_bit(0x50, 7); // DGPU_RST
78 udelay(100);
79 pmh7_register_clear_bit(0x50, 3); // DGPU_PWR
80 }
81}
82
83bool pmh7_dgpu_power_state(void)
84{
85 return (pmh7_register_read(0x50) & 0x08) == 8;
86}
87
Sven Schnelle4a6c9d12011-02-01 10:44:26 +000088void pmh7_register_set_bit(int reg, int bit)
89{
90 char val;
91
Alexander Couzens74ab0312018-08-17 18:36:56 +020092 val = pmh7_register_read(reg);
93 pmh7_register_write(reg, val | (1 << bit));
Sven Schnelle4a6c9d12011-02-01 10:44:26 +000094}
95
96void pmh7_register_clear_bit(int reg, int bit)
97{
98 char val;
99
Alexander Couzens74ab0312018-08-17 18:36:56 +0200100 val = pmh7_register_read(reg);
101 pmh7_register_write(reg, val & ~(1 << bit));
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000102}
103
104char pmh7_register_read(int reg)
105{
Alexander Couzens86b8d172018-08-17 18:47:52 +0200106 outb(reg & 0xff, EC_LENOVO_PMH7_ADDR_L);
107 outb((reg & 0xff00) >> 8, EC_LENOVO_PMH7_ADDR_H);
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000108 return inb(EC_LENOVO_PMH7_DATA);
109}
110
111void pmh7_register_write(int reg, int val)
112{
Alexander Couzens86b8d172018-08-17 18:47:52 +0200113 outb(reg & 0xff, EC_LENOVO_PMH7_ADDR_L);
114 outb((reg & 0xff00) >> 8, EC_LENOVO_PMH7_ADDR_H);
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000115 outb(val, EC_LENOVO_PMH7_DATA);
116}
117
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100118static void enable_dev(struct device *dev)
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000119{
Kyösti Mälkkie405c272019-08-17 05:28:38 +0300120 const struct ec_lenovo_pmh7_config *conf = dev->chip_info;
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000121 struct resource *resource;
Sven Schnelle51e1bc32011-06-05 21:32:51 +0200122 u8 val;
Uwe Hermann539500e2011-02-02 23:56:15 +0000123
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000124 resource = new_resource(dev, EC_LENOVO_PMH7_INDEX);
125 resource->flags = IORESOURCE_IO | IORESOURCE_FIXED;
126 resource->base = EC_LENOVO_PMH7_BASE;
127 resource->size = 16;
128 resource->align = 5;
129 resource->gran = 5;
Sven Schnelle1fa61eb2011-04-11 19:43:50 +0000130
131 pmh7_backlight_enable(conf->backlight_enable);
Sven Schnelle1b9d2ee2011-04-17 12:54:32 +0000132 pmh7_dock_event_enable(conf->dock_event_enable);
Sven Schnelle51e1bc32011-06-05 21:32:51 +0200133
Vladimir Serbinenko2c876682013-11-13 18:31:24 +0100134 if (get_option(&val, "touchpad") != CB_SUCCESS)
135 val = 1;
136 pmh7_touchpad_enable(val);
Vladimir Serbinenkoeada34f2014-01-11 04:22:35 +0100137
138 if (get_option(&val, "trackpoint") != CB_SUCCESS)
139 val = 1;
140 pmh7_trackpoint_enable(val);
Patrick Rudolph3b0f5422017-07-28 17:34:49 +0200141
142 printk(BIOS_INFO, "PMH7: ID %02x Revision %02x\n",
143 pmh7_register_read(EC_LENOVO_PMH7_REG_ID),
144 pmh7_register_read(EC_LENOVO_PMH7_REG_REV));
Sven Schnelle4a6c9d12011-02-01 10:44:26 +0000145}
146
147struct chip_operations ec_lenovo_pmh7_ops = {
148 CHIP_NAME("Lenovo Power Management Hardware Hub 7")
149 .enable_dev = enable_dev,
150};