coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
dock.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/device.h>
4 #include <arch/io.h>
5 #include <delay.h>
6 #include "dock.h"
8 #include "ec/acpi/ec.h"
9 #include "ec/lenovo/pmh7/pmh7.h"
11 
12 #define DLPC_CONTROL 0x164c
13 
14 static void dlpc_write_register(int reg, int value)
15 {
16  outb(reg, 0x164e);
17  outb(value, 0x164f);
18 }
19 
20 static u8 dlpc_read_register(int reg)
21 {
22  outb(reg, 0x164e);
23  return inb(0x164f);
24 }
25 
26 static void dock_write_register(int reg, int value)
27 {
28  outb(reg, 0x2e);
29  outb(value, 0x2f);
30 }
31 
32 static u8 dock_read_register(int reg)
33 {
34  outb(reg, 0x2e);
35  return inb(0x2f);
36 }
37 
38 static void dlpc_gpio_set_mode(int port, int mode)
39 {
41  dlpc_write_register(0xf1, mode);
42 }
43 
44 static void dock_gpio_set_mode(int port, int mode, int irq)
45 {
47  dock_write_register(0xf1, mode);
48  dock_write_register(0xf2, irq);
49 }
50 
51 static void dlpc_gpio_init(void)
52 {
53  /* Select GPIO module */
54  dlpc_write_register(0x07, 0x07);
55  /* GPIO Base Address 0x1680 */
56  dlpc_write_register(0x60, 0x16);
57  dlpc_write_register(0x61, 0x80);
58 
59  /* Activate GPIO */
60  dlpc_write_register(0x30, 0x01);
61 
62  dlpc_gpio_set_mode(0x00, 3);
63  dlpc_gpio_set_mode(0x01, 3);
64  dlpc_gpio_set_mode(0x02, 0);
65  dlpc_gpio_set_mode(0x03, 3);
66  dlpc_gpio_set_mode(0x04, 4);
67  dlpc_gpio_set_mode(0x20, 4);
68  dlpc_gpio_set_mode(0x21, 4);
69  dlpc_gpio_set_mode(0x23, 4);
70 }
71 
72 int dlpc_init(void)
73 {
74  int timeout = 1000;
75 
76  /* Enable 14.318MHz CLK on CLKIN */
77  dlpc_write_register(0x29, 0xa0);
78  while (!(dlpc_read_register(0x29) & 0x10) && timeout--)
79  udelay(1000);
80 
81  if (!timeout)
82  return 1;
83 
84  /* Select DLPC module */
85  dlpc_write_register(0x07, 0x19);
86  /* DLPC Base Address */
87  dlpc_write_register(0x60, (DLPC_CONTROL >> 8) & 0xff);
88  dlpc_write_register(0x61, DLPC_CONTROL & 0xff);
89  /* Activate DLPC */
90  dlpc_write_register(0x30, 0x01);
91 
92  /* Reset docking state */
93  outb(0x00, DLPC_CONTROL);
94 
96  return 0;
97 }
98 
99 static int dock_superio_init(void)
100 {
101  int timeout = 1000;
102  /* startup 14.318MHz Clock */
103  dock_write_register(0x29, 0xa0);
104  /* wait until clock is settled */
105  while (!(dock_read_register(0x29) & 0x10) && timeout--)
106  udelay(1000);
107 
108  if (!timeout)
109  return 1;
110 
111  /* set GPIO pins to Serial/Parallel Port
112  * functions
113  */
114  dock_write_register(0x22, 0xa9);
115 
116  /* enable serial port */
118  dock_write_register(0x30, 0x01);
119 
121  dock_write_register(0x60, 0x16);
122  dock_write_register(0x61, 0x20);
123  /* enable GPIO */
124  dock_write_register(0x30, 0x01);
125 
128 
130  PC87384_GPIO_PIN_OE, 0x00);
131 
133  PC87384_GPIO_PIN_OE, 0x00);
134 
137 
140 
143 
146 
149 
150  /* no GPIO events enabled for PORT0 */
151  outb(0x00, 0x1622);
152  /* clear GPIO events on PORT0 */
153  outb(0xff, 0x1623);
154  outb(0xff, 0x1624);
155  /* no GPIO events enabled for PORT1 */
156  outb(0x00, 0x1626);
157 
158  /* clear GPIO events on PORT1*/
159  outb(0xff, 0x1627);
160  outb(0x1F, 0x1628);
161  outb(0xfd, 0x1620);
162  return 0;
163 }
164 
165 int dock_connect(void)
166 {
167  int timeout = 1000;
168 
169  outb(0x07, DLPC_CONTROL);
170 
171  timeout = 1000;
172 
173  while (!(inb(DLPC_CONTROL) & 8) && timeout--)
174  udelay(1000);
175 
176  if (!timeout) {
177  /* docking failed, disable DLPC switch */
178  outb(0x00, DLPC_CONTROL);
179  dlpc_write_register(0x30, 0x00);
180  return 1;
181  }
182 
183  /* Assert D_PLTRST# */
184  outb(0xfe, 0x1680);
185  udelay(1000);
186  /* Deassert D_PLTRST# */
187  outb(0xff, 0x1680);
188  udelay(10000);
189 
190  return dock_superio_init();
191 }
192 
193 void dock_disconnect(void)
194 {
195  /* disconnect LPC bus */
196  outb(0x00, DLPC_CONTROL);
197  /* Assert PLTRST and DLPCPD */
198  outb(0xfc, 0x1680);
199 }
200 
201 int dock_present(void)
202 {
203  return pmh7_register_read(0x61) & 1;
204 }
205 
207 {
208  return !(inb(DEFAULT_GPIOBASE + 0x0c) & 0x40);
209 }
210 
211 void legacy_io_init(void)
212 {
213  /* Enable Power for Ultrabay slot */
215  udelay(100000);
217 }
pte_t value
Definition: mmu.c:91
u8 inb(u16 port)
void outb(u8 val, u16 port)
port
Definition: i915.h:29
#define PC87384_GPIO_PIN_OE
Definition: pc87384.h:11
#define PC87384_GPIO
Definition: pc87384.h:9
#define PC87384_SP1
Definition: pc87384.h:8
#define PC87384_GPIO_PIN_DEBOUNCE
Definition: pc87384.h:17
#define PC87384_GPIO_PIN_TYPE_PUSH_PULL
Definition: pc87384.h:12
#define PC87384_GPIO_PIN_PULLUP
Definition: pc87384.h:13
void pmh7_ultrabay_power_enable(int onoff)
Definition: pmh7.c:46
char pmh7_register_read(int reg)
Definition: pmh7.c:90
#define DEFAULT_GPIOBASE
Definition: pch.h:22
uint8_t u8
Definition: stdint.h:45
void dock_connect(void)
Definition: dock.c:215
void dock_disconnect(void)
Definition: dock.c:234
int dock_present(void)
Definition: dock.c:36
static void dlpc_gpio_set_mode(int port, int mode)
Definition: dock.c:38
static u8 dlpc_read_register(int reg)
Definition: dock.c:20
int dlpc_init(void)
Definition: dock.c:72
static void dock_write_register(int reg, int value)
Definition: dock.c:26
static void dlpc_write_register(int reg, int value)
Definition: dock.c:14
static u8 dock_read_register(int reg)
Definition: dock.c:32
#define DLPC_CONTROL
Definition: dock.c:12
void legacy_io_init(void)
Definition: dock.c:211
static int dock_superio_init(void)
Definition: dock.c:99
static void dlpc_gpio_init(void)
Definition: dock.c:51
int legacy_io_present(void)
Definition: dock.c:206
static void dock_gpio_set_mode(int port, int mode, int irq)
Definition: dock.c:44
void udelay(uint32_t us)
Definition: udelay.c:15