xref: /aosp_15_r20/external/coreboot/src/superio/common/conf_mode.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <device/device.h>
5 #include <superio/conf_mode.h>
6 #include <acpi/acpigen.h>
7 
8 /* Common enter/exit implementations */
9 
pnp_enter_conf_mode_55(struct device * dev)10 void pnp_enter_conf_mode_55(struct device *dev)
11 {
12 	outb(0x55, dev->path.pnp.port);
13 }
14 
pnp_enter_conf_mode_6767(struct device * dev)15 void pnp_enter_conf_mode_6767(struct device *dev)
16 {
17 	outb(0x67, dev->path.pnp.port);
18 	outb(0x67, dev->path.pnp.port);
19 }
20 
pnp_enter_conf_mode_7777(struct device * dev)21 void pnp_enter_conf_mode_7777(struct device *dev)
22 {
23 	outb(0x77, dev->path.pnp.port);
24 	outb(0x77, dev->path.pnp.port);
25 }
26 
pnp_enter_conf_mode_8787(struct device * dev)27 void pnp_enter_conf_mode_8787(struct device *dev)
28 {
29 	outb(0x87, dev->path.pnp.port);
30 	outb(0x87, dev->path.pnp.port);
31 }
32 
pnp_enter_conf_mode_a0a0(struct device * dev)33 void pnp_enter_conf_mode_a0a0(struct device *dev)
34 {
35 	outb(0xa0, dev->path.pnp.port);
36 	outb(0xa0, dev->path.pnp.port);
37 }
38 
pnp_enter_conf_mode_a5a5(struct device * dev)39 void pnp_enter_conf_mode_a5a5(struct device *dev)
40 {
41 	outb(0xa5, dev->path.pnp.port);
42 	outb(0xa5, dev->path.pnp.port);
43 }
44 
pnp_exit_conf_mode_aa(struct device * dev)45 void pnp_exit_conf_mode_aa(struct device *dev)
46 {
47 	outb(0xaa, dev->path.pnp.port);
48 }
49 
pnp_enter_conf_mode_870155aa(struct device * dev)50 void pnp_enter_conf_mode_870155aa(struct device *dev)
51 {
52 	outb(0x87, dev->path.pnp.port);
53 	outb(0x01, dev->path.pnp.port);
54 	outb(0x55, dev->path.pnp.port);
55 
56 	if (dev->path.pnp.port == 0x4e)
57 		outb(0xaa, dev->path.pnp.port);
58 	else
59 		outb(0x55, dev->path.pnp.port);
60 }
61 
pnp_exit_conf_mode_0202(struct device * dev)62 void pnp_exit_conf_mode_0202(struct device *dev)
63 {
64 	pnp_write_config(dev, 0x02, (1 << 1));
65 }
66 
67 /* Functions for ACPI */
68 #if CONFIG(HAVE_ACPI_TABLES)
pnp_ssdt_enter_conf_mode_55(struct device * dev,const char * idx,const char * data)69 static void pnp_ssdt_enter_conf_mode_55(struct device *dev, const char *idx, const char *data)
70 {
71 	acpigen_write_store();
72 	acpigen_write_byte(0x55);
73 	acpigen_emit_namestring(idx);
74 }
75 
pnp_ssdt_enter_conf_mode_6767(struct device * dev,const char * idx,const char * data)76 static void pnp_ssdt_enter_conf_mode_6767(struct device *dev, const char *idx, const char *data)
77 {
78 	acpigen_write_store();
79 	acpigen_write_byte(0x67);
80 	acpigen_emit_namestring(idx);
81 
82 	acpigen_write_store();
83 	acpigen_write_byte(0x67);
84 	acpigen_emit_namestring(idx);
85 }
86 
pnp_ssdt_enter_conf_mode_7777(struct device * dev,const char * idx,const char * data)87 static void pnp_ssdt_enter_conf_mode_7777(struct device *dev, const char *idx, const char *data)
88 {
89 	acpigen_write_store();
90 	acpigen_write_byte(0x77);
91 	acpigen_emit_namestring(idx);
92 
93 	acpigen_write_store();
94 	acpigen_write_byte(0x77);
95 	acpigen_emit_namestring(idx);
96 }
97 
pnp_ssdt_enter_conf_mode_8787(struct device * dev,const char * idx,const char * data)98 static void pnp_ssdt_enter_conf_mode_8787(struct device *dev, const char *idx, const char *data)
99 {
100 	acpigen_write_store();
101 	acpigen_write_byte(0x87);
102 	acpigen_emit_namestring(idx);
103 
104 	acpigen_write_store();
105 	acpigen_write_byte(0x87);
106 	acpigen_emit_namestring(idx);
107 }
108 
pnp_ssdt_enter_conf_mode_a0a0(struct device * dev,const char * idx,const char * data)109 static void pnp_ssdt_enter_conf_mode_a0a0(struct device *dev, const char *idx, const char *data)
110 {
111 	acpigen_write_store();
112 	acpigen_write_byte(0xa0);
113 	acpigen_emit_namestring(idx);
114 
115 	acpigen_write_store();
116 	acpigen_write_byte(0xa0);
117 	acpigen_emit_namestring(idx);
118 }
119 
pnp_ssdt_enter_conf_mode_a5a5(struct device * dev,const char * idx,const char * data)120 static void pnp_ssdt_enter_conf_mode_a5a5(struct device *dev, const char *idx, const char *data)
121 {
122 	acpigen_write_store();
123 	acpigen_write_byte(0xa5);
124 	acpigen_emit_namestring(idx);
125 
126 	acpigen_write_store();
127 	acpigen_write_byte(0xa5);
128 	acpigen_emit_namestring(idx);
129 }
130 
pnp_ssdt_enter_conf_mode_870155aa(struct device * dev,const char * idx,const char * data)131 static void pnp_ssdt_enter_conf_mode_870155aa(struct device *dev,
132 					      const char *idx, const char *data)
133 {
134 	acpigen_write_store();
135 	acpigen_write_byte(0x87);
136 	acpigen_emit_namestring(idx);
137 
138 	acpigen_write_store();
139 	acpigen_write_byte(0x01);
140 	acpigen_emit_namestring(idx);
141 
142 	acpigen_write_store();
143 	acpigen_write_byte(0x55);
144 	acpigen_emit_namestring(idx);
145 
146 	acpigen_write_store();
147 	if (dev->path.pnp.port == 0x4e)
148 		acpigen_write_byte(0xaa);
149 	else
150 		acpigen_write_byte(0x55);
151 	acpigen_emit_namestring(idx);
152 }
153 
pnp_ssdt_exit_conf_mode_aa(struct device * dev,const char * idx,const char * data)154 static void pnp_ssdt_exit_conf_mode_aa(struct device *dev, const char *idx, const char *data)
155 {
156 	acpigen_write_store();
157 	acpigen_write_byte(0xaa);
158 	acpigen_emit_namestring(idx);
159 }
160 
pnp_ssdt_exit_conf_mode_0202(struct device * dev,const char * idx,const char * data)161 static void pnp_ssdt_exit_conf_mode_0202(struct device *dev, const char *idx, const char *data)
162 {
163 	acpigen_write_store();
164 	acpigen_write_byte(0x02);
165 	acpigen_emit_namestring(idx);
166 
167 	acpigen_write_store();
168 	acpigen_write_byte(0x02);
169 	acpigen_emit_namestring(data);
170 }
171 #endif
172 
173 const struct pnp_mode_ops pnp_conf_mode_55_aa = {
174 	.enter_conf_mode = pnp_enter_conf_mode_55,
175 	.exit_conf_mode  = pnp_exit_conf_mode_aa,
176 #if CONFIG(HAVE_ACPI_TABLES)
177 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_55,
178 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
179 #endif
180 };
181 
182 const struct pnp_mode_ops pnp_conf_mode_6767_aa = {
183 	.enter_conf_mode = pnp_enter_conf_mode_6767,
184 	.exit_conf_mode  = pnp_exit_conf_mode_aa,
185 #if CONFIG(HAVE_ACPI_TABLES)
186 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_6767,
187 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
188 #endif
189 };
190 
191 const struct pnp_mode_ops pnp_conf_mode_7777_aa = {
192 	.enter_conf_mode = pnp_enter_conf_mode_7777,
193 	.exit_conf_mode  = pnp_exit_conf_mode_aa,
194 #if CONFIG(HAVE_ACPI_TABLES)
195 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_7777,
196 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
197 #endif
198 };
199 
200 const struct pnp_mode_ops pnp_conf_mode_8787_aa = {
201 	.enter_conf_mode = pnp_enter_conf_mode_8787,
202 	.exit_conf_mode  = pnp_exit_conf_mode_aa,
203 #if CONFIG(HAVE_ACPI_TABLES)
204 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_8787,
205 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
206 #endif
207 };
208 
209 const struct pnp_mode_ops pnp_conf_mode_a0a0_aa = {
210 	.enter_conf_mode = pnp_enter_conf_mode_a0a0,
211 	.exit_conf_mode  = pnp_exit_conf_mode_aa,
212 #if CONFIG(HAVE_ACPI_TABLES)
213 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_a0a0,
214 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
215 #endif
216 };
217 
218 const struct pnp_mode_ops pnp_conf_mode_a5a5_aa = {
219 	.enter_conf_mode = pnp_enter_conf_mode_a5a5,
220 	.exit_conf_mode  = pnp_exit_conf_mode_aa,
221 #if CONFIG(HAVE_ACPI_TABLES)
222 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_a5a5,
223 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa,
224 #endif
225 };
226 
227 const struct pnp_mode_ops pnp_conf_mode_870155_aa = {
228 	.enter_conf_mode = pnp_enter_conf_mode_870155aa,
229 	.exit_conf_mode  = pnp_exit_conf_mode_0202,
230 #if CONFIG(HAVE_ACPI_TABLES)
231 	.ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_870155aa,
232 	.ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_0202,
233 #endif
234 };
235