1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include <acpi/acpigen.h>
4 #include <stdio.h>
5
6 #include "i915.h"
7
8 void
drivers_intel_gma_displays_ssdt_generate(const struct i915_gpu_controller_info * conf)9 drivers_intel_gma_displays_ssdt_generate(const struct i915_gpu_controller_info *conf)
10 {
11 size_t i;
12 const char *names[] = { "UNK", "VGA", "TV", "DVI", "LCD" };
13 int counters[ARRAY_SIZE(names)] = { 0 };
14
15 if (!conf->ndid)
16 return;
17
18 acpigen_write_scope("\\_SB.PCI0.GFX0");
19
20 /*
21 Method (_DOD, 0)
22 {
23 Return (Package() {
24 0x5a5a5a5a,
25 0x5a5a5a5a,
26 0x5a5a5a5a
27 })
28 }
29 */
30 acpigen_write_method("_DOD", 0);
31
32 acpigen_emit_byte(RETURN_OP);
33 acpigen_write_package(conf->ndid);
34 for (i = 0; i < conf->ndid; i++) {
35 acpigen_write_dword(conf->did[i] | 0x80010000);
36 }
37 acpigen_pop_len(); /* End Package. */
38
39 acpigen_pop_len(); /* End Method. */
40
41 for (i = 0; i < conf->ndid; i++) {
42 char name[5];
43 int kind;
44
45 kind = (conf->did[i] >> 8) & 0xf;
46 if (kind >= ARRAY_SIZE(names)) {
47 kind = 0;
48 }
49
50 snprintf(name, sizeof(name), "%s%d", names[kind], counters[kind]);
51 counters[kind]++;
52
53 /* Device (LCD0) */
54 acpigen_write_device(name);
55
56 /* Name (_ADR, 0x0410) */
57 acpigen_write_name_dword("_ADR", conf->did[i] & 0xffff);
58
59 /* ACPI brightness for LCD. */
60 if (kind == 4) {
61 /*
62 Method (_BCL, 0, NotSerialized)
63 {
64 Return (^^XBCL())
65 }
66 */
67 acpigen_write_method("_BCL", 0);
68 acpigen_emit_byte(RETURN_OP);
69 acpigen_emit_namestring("^^XBCL");
70 acpigen_pop_len();
71
72 /*
73 Method (_BCM, 1, NotSerialized)
74 {
75 ^^XBCM(Arg0)
76 }
77 */
78 acpigen_write_method("_BCM", 1);
79 acpigen_emit_namestring("^^XBCM");
80 acpigen_emit_byte(ARG0_OP);
81 acpigen_pop_len();
82
83 /*
84 Method (_BQC, 0, NotSerialized)
85 {
86 Return (^^XBQC())
87 }
88 */
89 acpigen_write_method("_BQC", 0);
90 acpigen_emit_byte(RETURN_OP);
91 acpigen_emit_namestring("^^XBQC");
92 acpigen_pop_len();
93 }
94
95 /*
96 * _DCS, _DGS and _DSS are required by specification. However,
97 * we never implemented them properly, and no OS driver com-
98 * plained yet. So we stub them out and keep the traditional
99 * behavior in case an OS driver checks for their existence.
100 */
101
102 /*
103 Method(_DCS, 0)
104 {
105 Return (0x1d)
106 }
107 */
108 acpigen_write_method("_DCS", 0);
109 acpigen_write_return_integer(0x1d);
110 acpigen_pop_len();
111
112 /*
113 Method(_DGS, 0)
114 {
115 Return (0)
116 }
117 */
118 acpigen_write_method("_DGS", 0);
119 acpigen_write_return_integer(0);
120 acpigen_pop_len();
121
122 /*
123 Method(_DSS, 1)
124 {
125 }
126 */
127 acpigen_write_method("_DSS", 1);
128 acpigen_pop_len();
129
130 acpigen_pop_len(); /* End Device. */
131 }
132
133 acpigen_pop_len(); /* End Scope. */
134 }
135