blob: c3a9b8a266aa66c5ba635e7cef894dcdd49b21be [file] [log] [blame]
Vladimir Serbinenkodd2bc3f2014-10-31 09:16:31 +01001/*
2 * Copyright (C) 2014 Vladimir Serbinenko
3 * Subject to the GNU GPL v2, or (at your option) any later version.
4 */
5
6#include <arch/acpi.h>
7#include <arch/acpigen.h>
8#include <string.h>
9#include "i915.h"
10
11void
12drivers_intel_gma_displays_ssdt_generate(const struct i915_gpu_controller_info *conf)
13{
14 size_t i;
15 const char *names[] = { "UNK", "VGA", "TV", "DVI", "LCD" };
16 int counters[ARRAY_SIZE(names)];
17
18 memset(counters, 0, sizeof(counters));
19
20 acpigen_write_scope("\\_SB.PCI0.GFX0");
21
22 /*
23 Method (_DOD, 0)
24 {
25 Return (Package() {
26 0x5a5a5a5a,
27 0x5a5a5a5a,
28 0x5a5a5a5a
29 })
30 }
31 */
32 acpigen_write_method("_DOD", 0);
33 acpigen_emit_byte(0xa4); /* ReturnOp. */
34 acpigen_write_package(conf->ndid);
35
36 for (i = 0; i < conf->ndid; i++) {
37 acpigen_write_dword (conf->did[i] | 0x80010000);
38 }
39 acpigen_pop_len(); /* End Package. */
40 acpigen_pop_len(); /* End Method. */
41
42 for (i = 0; i < conf->ndid; i++) {
43 char name[10];
44 char *ptr;
45 int kind;
46 kind = (conf->did[i] >> 8) & 0xf;
47 if (kind >= ARRAY_SIZE(names)) {
48 kind = 0;
49 }
50 strcpy(name, names[kind]);
51 for (ptr = name; *ptr; ptr++);
52 *ptr++ = counters[kind] + '0';
53 *ptr++ = '\0';
54 counters[kind]++;
55 acpigen_write_device(name);
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(0xa4); /* ReturnOp. */
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(0x68); /* Arg0Op. */
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(0xa4); /* ReturnOp. */
91 acpigen_emit_namestring("^^XBQC");
92 acpigen_pop_len();
93 }
94
95 /*
96 Method(_DCS, 0)
97 {
98 Return (^^XDCS(<device number>))
99 }
100 */
101 acpigen_write_method("_DCS", 0);
102 acpigen_emit_byte(0xa4); /* ReturnOp. */
103 acpigen_emit_namestring("^^XDCS");
104 acpigen_write_byte(i);
105 acpigen_pop_len();
106
107 /*
108 Method(_DGS, 0)
109 {
110 Return (^^XDGS(<device number>))
111 }
112 */
113 acpigen_write_method("_DGS", 0);
114 acpigen_emit_byte(0xa4); /* ReturnOp. */
115 acpigen_emit_namestring("^^XDGS");
116 acpigen_write_byte(i);
117 acpigen_pop_len();
118
119 /*
120 Method(_DSS, 1)
121 {
122 ^^XDSS(0x5a, Arg0)
123 }
124 */
125 acpigen_write_method("_DSS", 0);
126 acpigen_emit_namestring("^^XDSS");
127 acpigen_write_byte(i);
128 acpigen_emit_byte(0x68); /* Arg0Op. */
129 acpigen_pop_len();
130
131 acpigen_pop_len();
132 }
133
134 acpigen_pop_len();
135}