Subversion Repositories Kolibri OS

Rev

Rev 6084 | Rev 6660 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6084 Rev 6103
1
/*
1
/*
2
 * Copyright 2008 Intel Corporation 
2
 * Copyright 2008 Intel Corporation 
3
 * Copyright 2008 Red Hat 
3
 * Copyright 2008 Red Hat 
4
 *
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining
5
 * Permission is hereby granted, free of charge, to any person obtaining
6
 * a copy of this software and associated documentation files (the
6
 * a copy of this software and associated documentation files (the
7
 * "Software"), to deal in the Software without restriction, including
7
 * "Software"), to deal in the Software without restriction, including
8
 * without limitation the rights to use, copy, modify, merge, publish,
8
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * distribute, sub license, and/or sell copies of the Software, and to
9
 * distribute, sub license, and/or sell copies of the Software, and to
10
 * permit persons to whom the Software is furnished to do so, subject to
10
 * permit persons to whom the Software is furnished to do so, subject to
11
 * the following conditions:
11
 * the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice (including the
13
 * The above copyright notice and this permission notice (including the
14
 * next paragraph) shall be included in all copies or substantial
14
 * next paragraph) shall be included in all copies or substantial
15
 * portions of the Software.
15
 * portions of the Software.
16
 *
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
 * NON-INFRINGEMENT.  IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
20
 * NON-INFRINGEMENT.  IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
21
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
 * SOFTWARE.
24
 * SOFTWARE.
25
 *
25
 *
26
 */
26
 */
27
 
-
 
28
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 
29
 
27
 
30
#include 
28
#include 
31
#include 
29
#include 
32
 
30
 
33
#include 
31
#include 
34
#include 
32
#include 
35
#include "i915_drv.h"
33
#include "i915_drv.h"
36
#include "intel_drv.h"
34
#include "intel_drv.h"
37
 
35
 
38
#define PCI_ASLE		0xe4
36
#define PCI_ASLE		0xe4
39
#define PCI_ASLS		0xfc
37
#define PCI_ASLS		0xfc
40
#define PCI_SWSCI		0xe8
38
#define PCI_SWSCI		0xe8
41
#define PCI_SWSCI_SCISEL	(1 << 15)
39
#define PCI_SWSCI_SCISEL	(1 << 15)
42
#define PCI_SWSCI_GSSCIE	(1 << 0)
40
#define PCI_SWSCI_GSSCIE	(1 << 0)
43
 
41
 
44
#define OPREGION_HEADER_OFFSET 0
42
#define OPREGION_HEADER_OFFSET 0
45
#define OPREGION_ACPI_OFFSET   0x100
43
#define OPREGION_ACPI_OFFSET   0x100
46
#define   ACPI_CLID 0x01ac /* current lid state indicator */
44
#define   ACPI_CLID 0x01ac /* current lid state indicator */
47
#define   ACPI_CDCK 0x01b0 /* current docking state indicator */
45
#define   ACPI_CDCK 0x01b0 /* current docking state indicator */
48
#define OPREGION_SWSCI_OFFSET  0x200
46
#define OPREGION_SWSCI_OFFSET  0x200
49
#define OPREGION_ASLE_OFFSET   0x300
47
#define OPREGION_ASLE_OFFSET   0x300
50
#define OPREGION_VBT_OFFSET    0x400
48
#define OPREGION_VBT_OFFSET    0x400
51
 
49
 
52
#define OPREGION_SIGNATURE "IntelGraphicsMem"
50
#define OPREGION_SIGNATURE "IntelGraphicsMem"
53
#define MBOX_ACPI      (1<<0)
51
#define MBOX_ACPI      (1<<0)
54
#define MBOX_SWSCI     (1<<1)
52
#define MBOX_SWSCI     (1<<1)
55
#define MBOX_ASLE      (1<<2)
53
#define MBOX_ASLE      (1<<2)
56
#define MBOX_ASLE_EXT  (1<<4)
54
#define MBOX_ASLE_EXT  (1<<4)
57
 
55
 
58
struct opregion_header {
56
struct opregion_header {
59
	u8 signature[16];
57
	u8 signature[16];
60
	u32 size;
58
	u32 size;
61
	u32 opregion_ver;
59
	u32 opregion_ver;
62
	u8 bios_ver[32];
60
	u8 bios_ver[32];
63
	u8 vbios_ver[16];
61
	u8 vbios_ver[16];
64
	u8 driver_ver[16];
62
	u8 driver_ver[16];
65
	u32 mboxes;
63
	u32 mboxes;
66
	u32 driver_model;
64
	u32 driver_model;
67
	u32 pcon;
65
	u32 pcon;
68
	u8 dver[32];
66
	u8 dver[32];
69
	u8 rsvd[124];
67
	u8 rsvd[124];
70
} __packed;
68
} __packed;
71
 
69
 
72
/* OpRegion mailbox #1: public ACPI methods */
70
/* OpRegion mailbox #1: public ACPI methods */
73
struct opregion_acpi {
71
struct opregion_acpi {
74
	u32 drdy;       /* driver readiness */
72
	u32 drdy;       /* driver readiness */
75
	u32 csts;       /* notification status */
73
	u32 csts;       /* notification status */
76
	u32 cevt;       /* current event */
74
	u32 cevt;       /* current event */
77
	u8 rsvd1[20];
75
	u8 rsvd1[20];
78
	u32 didl[8];    /* supported display devices ID list */
76
	u32 didl[8];    /* supported display devices ID list */
79
	u32 cpdl[8];    /* currently presented display list */
77
	u32 cpdl[8];    /* currently presented display list */
80
	u32 cadl[8];    /* currently active display list */
78
	u32 cadl[8];    /* currently active display list */
81
	u32 nadl[8];    /* next active devices list */
79
	u32 nadl[8];    /* next active devices list */
82
	u32 aslp;       /* ASL sleep time-out */
80
	u32 aslp;       /* ASL sleep time-out */
83
	u32 tidx;       /* toggle table index */
81
	u32 tidx;       /* toggle table index */
84
	u32 chpd;       /* current hotplug enable indicator */
82
	u32 chpd;       /* current hotplug enable indicator */
85
	u32 clid;       /* current lid state*/
83
	u32 clid;       /* current lid state*/
86
	u32 cdck;       /* current docking state */
84
	u32 cdck;       /* current docking state */
87
	u32 sxsw;       /* Sx state resume */
85
	u32 sxsw;       /* Sx state resume */
88
	u32 evts;       /* ASL supported events */
86
	u32 evts;       /* ASL supported events */
89
	u32 cnot;       /* current OS notification */
87
	u32 cnot;       /* current OS notification */
90
	u32 nrdy;       /* driver status */
88
	u32 nrdy;       /* driver status */
91
	u32 did2[7];	/* extended supported display devices ID list */
89
	u32 did2[7];	/* extended supported display devices ID list */
92
	u32 cpd2[7];	/* extended attached display devices list */
90
	u32 cpd2[7];	/* extended attached display devices list */
93
	u8 rsvd2[4];
91
	u8 rsvd2[4];
94
} __packed;
92
} __packed;
95
 
93
 
96
/* OpRegion mailbox #2: SWSCI */
94
/* OpRegion mailbox #2: SWSCI */
97
struct opregion_swsci {
95
struct opregion_swsci {
98
	u32 scic;       /* SWSCI command|status|data */
96
	u32 scic;       /* SWSCI command|status|data */
99
	u32 parm;       /* command parameters */
97
	u32 parm;       /* command parameters */
100
	u32 dslp;       /* driver sleep time-out */
98
	u32 dslp;       /* driver sleep time-out */
101
	u8 rsvd[244];
99
	u8 rsvd[244];
102
} __packed;
100
} __packed;
103
 
101
 
104
/* OpRegion mailbox #3: ASLE */
102
/* OpRegion mailbox #3: ASLE */
105
struct opregion_asle {
103
struct opregion_asle {
106
	u32 ardy;       /* driver readiness */
104
	u32 ardy;       /* driver readiness */
107
	u32 aslc;       /* ASLE interrupt command */
105
	u32 aslc;       /* ASLE interrupt command */
108
	u32 tche;       /* technology enabled indicator */
106
	u32 tche;       /* technology enabled indicator */
109
	u32 alsi;       /* current ALS illuminance reading */
107
	u32 alsi;       /* current ALS illuminance reading */
110
	u32 bclp;       /* backlight brightness to set */
108
	u32 bclp;       /* backlight brightness to set */
111
	u32 pfit;       /* panel fitting state */
109
	u32 pfit;       /* panel fitting state */
112
	u32 cblv;       /* current brightness level */
110
	u32 cblv;       /* current brightness level */
113
	u16 bclm[20];   /* backlight level duty cycle mapping table */
111
	u16 bclm[20];   /* backlight level duty cycle mapping table */
114
	u32 cpfm;       /* current panel fitting mode */
112
	u32 cpfm;       /* current panel fitting mode */
115
	u32 epfm;       /* enabled panel fitting modes */
113
	u32 epfm;       /* enabled panel fitting modes */
116
	u8 plut[74];    /* panel LUT and identifier */
114
	u8 plut[74];    /* panel LUT and identifier */
117
	u32 pfmb;       /* PWM freq and min brightness */
115
	u32 pfmb;       /* PWM freq and min brightness */
118
	u32 cddv;       /* color correction default values */
116
	u32 cddv;       /* color correction default values */
119
	u32 pcft;       /* power conservation features */
117
	u32 pcft;       /* power conservation features */
120
	u32 srot;       /* supported rotation angles */
118
	u32 srot;       /* supported rotation angles */
121
	u32 iuer;       /* IUER events */
119
	u32 iuer;       /* IUER events */
122
	u64 fdss;
120
	u64 fdss;
123
	u32 fdsp;
121
	u32 fdsp;
124
	u32 stat;
122
	u32 stat;
125
	u8 rsvd[70];
123
	u8 rsvd[70];
126
} __packed;
124
} __packed;
127
 
125
 
128
/* Driver readiness indicator */
126
/* Driver readiness indicator */
129
#define ASLE_ARDY_READY		(1 << 0)
127
#define ASLE_ARDY_READY		(1 << 0)
130
#define ASLE_ARDY_NOT_READY	(0 << 0)
128
#define ASLE_ARDY_NOT_READY	(0 << 0)
131
 
129
 
132
/* ASLE Interrupt Command (ASLC) bits */
130
/* ASLE Interrupt Command (ASLC) bits */
133
#define ASLC_SET_ALS_ILLUM		(1 << 0)
131
#define ASLC_SET_ALS_ILLUM		(1 << 0)
134
#define ASLC_SET_BACKLIGHT		(1 << 1)
132
#define ASLC_SET_BACKLIGHT		(1 << 1)
135
#define ASLC_SET_PFIT			(1 << 2)
133
#define ASLC_SET_PFIT			(1 << 2)
136
#define ASLC_SET_PWM_FREQ		(1 << 3)
134
#define ASLC_SET_PWM_FREQ		(1 << 3)
137
#define ASLC_SUPPORTED_ROTATION_ANGLES	(1 << 4)
135
#define ASLC_SUPPORTED_ROTATION_ANGLES	(1 << 4)
138
#define ASLC_BUTTON_ARRAY		(1 << 5)
136
#define ASLC_BUTTON_ARRAY		(1 << 5)
139
#define ASLC_CONVERTIBLE_INDICATOR	(1 << 6)
137
#define ASLC_CONVERTIBLE_INDICATOR	(1 << 6)
140
#define ASLC_DOCKING_INDICATOR		(1 << 7)
138
#define ASLC_DOCKING_INDICATOR		(1 << 7)
141
#define ASLC_ISCT_STATE_CHANGE		(1 << 8)
139
#define ASLC_ISCT_STATE_CHANGE		(1 << 8)
142
#define ASLC_REQ_MSK			0x1ff
140
#define ASLC_REQ_MSK			0x1ff
143
/* response bits */
141
/* response bits */
144
#define ASLC_ALS_ILLUM_FAILED		(1 << 10)
142
#define ASLC_ALS_ILLUM_FAILED		(1 << 10)
145
#define ASLC_BACKLIGHT_FAILED		(1 << 12)
143
#define ASLC_BACKLIGHT_FAILED		(1 << 12)
146
#define ASLC_PFIT_FAILED		(1 << 14)
144
#define ASLC_PFIT_FAILED		(1 << 14)
147
#define ASLC_PWM_FREQ_FAILED		(1 << 16)
145
#define ASLC_PWM_FREQ_FAILED		(1 << 16)
148
#define ASLC_ROTATION_ANGLES_FAILED	(1 << 18)
146
#define ASLC_ROTATION_ANGLES_FAILED	(1 << 18)
149
#define ASLC_BUTTON_ARRAY_FAILED	(1 << 20)
147
#define ASLC_BUTTON_ARRAY_FAILED	(1 << 20)
150
#define ASLC_CONVERTIBLE_FAILED		(1 << 22)
148
#define ASLC_CONVERTIBLE_FAILED		(1 << 22)
151
#define ASLC_DOCKING_FAILED		(1 << 24)
149
#define ASLC_DOCKING_FAILED		(1 << 24)
152
#define ASLC_ISCT_STATE_FAILED		(1 << 26)
150
#define ASLC_ISCT_STATE_FAILED		(1 << 26)
153
 
151
 
154
/* Technology enabled indicator */
152
/* Technology enabled indicator */
155
#define ASLE_TCHE_ALS_EN	(1 << 0)
153
#define ASLE_TCHE_ALS_EN	(1 << 0)
156
#define ASLE_TCHE_BLC_EN	(1 << 1)
154
#define ASLE_TCHE_BLC_EN	(1 << 1)
157
#define ASLE_TCHE_PFIT_EN	(1 << 2)
155
#define ASLE_TCHE_PFIT_EN	(1 << 2)
158
#define ASLE_TCHE_PFMB_EN	(1 << 3)
156
#define ASLE_TCHE_PFMB_EN	(1 << 3)
159
 
157
 
160
/* ASLE backlight brightness to set */
158
/* ASLE backlight brightness to set */
161
#define ASLE_BCLP_VALID                (1<<31)
159
#define ASLE_BCLP_VALID                (1<<31)
162
#define ASLE_BCLP_MSK          (~(1<<31))
160
#define ASLE_BCLP_MSK          (~(1<<31))
163
 
161
 
164
/* ASLE panel fitting request */
162
/* ASLE panel fitting request */
165
#define ASLE_PFIT_VALID         (1<<31)
163
#define ASLE_PFIT_VALID         (1<<31)
166
#define ASLE_PFIT_CENTER (1<<0)
164
#define ASLE_PFIT_CENTER (1<<0)
167
#define ASLE_PFIT_STRETCH_TEXT (1<<1)
165
#define ASLE_PFIT_STRETCH_TEXT (1<<1)
168
#define ASLE_PFIT_STRETCH_GFX (1<<2)
166
#define ASLE_PFIT_STRETCH_GFX (1<<2)
169
 
167
 
170
/* PWM frequency and minimum brightness */
168
/* PWM frequency and minimum brightness */
171
#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
169
#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
172
#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
170
#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
173
#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
171
#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
174
#define ASLE_PFMB_PWM_VALID (1<<31)
172
#define ASLE_PFMB_PWM_VALID (1<<31)
175
 
173
 
176
#define ASLE_CBLV_VALID         (1<<31)
174
#define ASLE_CBLV_VALID         (1<<31)
177
 
175
 
178
/* IUER */
176
/* IUER */
179
#define ASLE_IUER_DOCKING		(1 << 7)
177
#define ASLE_IUER_DOCKING		(1 << 7)
180
#define ASLE_IUER_CONVERTIBLE		(1 << 6)
178
#define ASLE_IUER_CONVERTIBLE		(1 << 6)
181
#define ASLE_IUER_ROTATION_LOCK_BTN	(1 << 4)
179
#define ASLE_IUER_ROTATION_LOCK_BTN	(1 << 4)
182
#define ASLE_IUER_VOLUME_DOWN_BTN	(1 << 3)
180
#define ASLE_IUER_VOLUME_DOWN_BTN	(1 << 3)
183
#define ASLE_IUER_VOLUME_UP_BTN		(1 << 2)
181
#define ASLE_IUER_VOLUME_UP_BTN		(1 << 2)
184
#define ASLE_IUER_WINDOWS_BTN		(1 << 1)
182
#define ASLE_IUER_WINDOWS_BTN		(1 << 1)
185
#define ASLE_IUER_POWER_BTN		(1 << 0)
183
#define ASLE_IUER_POWER_BTN		(1 << 0)
186
 
184
 
187
/* Software System Control Interrupt (SWSCI) */
185
/* Software System Control Interrupt (SWSCI) */
188
#define SWSCI_SCIC_INDICATOR		(1 << 0)
186
#define SWSCI_SCIC_INDICATOR		(1 << 0)
189
#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT	1
187
#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT	1
190
#define SWSCI_SCIC_MAIN_FUNCTION_MASK	(0xf << 1)
188
#define SWSCI_SCIC_MAIN_FUNCTION_MASK	(0xf << 1)
191
#define SWSCI_SCIC_SUB_FUNCTION_SHIFT	8
189
#define SWSCI_SCIC_SUB_FUNCTION_SHIFT	8
192
#define SWSCI_SCIC_SUB_FUNCTION_MASK	(0xff << 8)
190
#define SWSCI_SCIC_SUB_FUNCTION_MASK	(0xff << 8)
193
#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT	8
191
#define SWSCI_SCIC_EXIT_PARAMETER_SHIFT	8
194
#define SWSCI_SCIC_EXIT_PARAMETER_MASK	(0xff << 8)
192
#define SWSCI_SCIC_EXIT_PARAMETER_MASK	(0xff << 8)
195
#define SWSCI_SCIC_EXIT_STATUS_SHIFT	5
193
#define SWSCI_SCIC_EXIT_STATUS_SHIFT	5
196
#define SWSCI_SCIC_EXIT_STATUS_MASK	(7 << 5)
194
#define SWSCI_SCIC_EXIT_STATUS_MASK	(7 << 5)
197
#define SWSCI_SCIC_EXIT_STATUS_SUCCESS	1
195
#define SWSCI_SCIC_EXIT_STATUS_SUCCESS	1
198
 
196
 
199
#define SWSCI_FUNCTION_CODE(main, sub) \
197
#define SWSCI_FUNCTION_CODE(main, sub) \
200
	((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
198
	((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
201
	 (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
199
	 (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
202
 
200
 
203
/* SWSCI: Get BIOS Data (GBDA) */
201
/* SWSCI: Get BIOS Data (GBDA) */
204
#define SWSCI_GBDA			4
202
#define SWSCI_GBDA			4
205
#define SWSCI_GBDA_SUPPORTED_CALLS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
203
#define SWSCI_GBDA_SUPPORTED_CALLS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
206
#define SWSCI_GBDA_REQUESTED_CALLBACKS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
204
#define SWSCI_GBDA_REQUESTED_CALLBACKS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
207
#define SWSCI_GBDA_BOOT_DISPLAY_PREF	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
205
#define SWSCI_GBDA_BOOT_DISPLAY_PREF	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
208
#define SWSCI_GBDA_PANEL_DETAILS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
206
#define SWSCI_GBDA_PANEL_DETAILS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
209
#define SWSCI_GBDA_TV_STANDARD		SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
207
#define SWSCI_GBDA_TV_STANDARD		SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
210
#define SWSCI_GBDA_INTERNAL_GRAPHICS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
208
#define SWSCI_GBDA_INTERNAL_GRAPHICS	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
211
#define SWSCI_GBDA_SPREAD_SPECTRUM	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
209
#define SWSCI_GBDA_SPREAD_SPECTRUM	SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
212
 
210
 
213
/* SWSCI: System BIOS Callbacks (SBCB) */
211
/* SWSCI: System BIOS Callbacks (SBCB) */
214
#define SWSCI_SBCB			6
212
#define SWSCI_SBCB			6
215
#define SWSCI_SBCB_SUPPORTED_CALLBACKS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
213
#define SWSCI_SBCB_SUPPORTED_CALLBACKS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
216
#define SWSCI_SBCB_INIT_COMPLETION	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
214
#define SWSCI_SBCB_INIT_COMPLETION	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
217
#define SWSCI_SBCB_PRE_HIRES_SET_MODE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
215
#define SWSCI_SBCB_PRE_HIRES_SET_MODE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
218
#define SWSCI_SBCB_POST_HIRES_SET_MODE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
216
#define SWSCI_SBCB_POST_HIRES_SET_MODE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
219
#define SWSCI_SBCB_DISPLAY_SWITCH	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
217
#define SWSCI_SBCB_DISPLAY_SWITCH	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
220
#define SWSCI_SBCB_SET_TV_FORMAT	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
218
#define SWSCI_SBCB_SET_TV_FORMAT	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
221
#define SWSCI_SBCB_ADAPTER_POWER_STATE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
219
#define SWSCI_SBCB_ADAPTER_POWER_STATE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
222
#define SWSCI_SBCB_DISPLAY_POWER_STATE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
220
#define SWSCI_SBCB_DISPLAY_POWER_STATE	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
223
#define SWSCI_SBCB_SET_BOOT_DISPLAY	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
221
#define SWSCI_SBCB_SET_BOOT_DISPLAY	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
224
#define SWSCI_SBCB_SET_PANEL_DETAILS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
222
#define SWSCI_SBCB_SET_PANEL_DETAILS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
225
#define SWSCI_SBCB_SET_INTERNAL_GFX	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
223
#define SWSCI_SBCB_SET_INTERNAL_GFX	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
226
#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
224
#define SWSCI_SBCB_POST_HIRES_TO_DOS_FS	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
227
#define SWSCI_SBCB_SUSPEND_RESUME	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
225
#define SWSCI_SBCB_SUSPEND_RESUME	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
228
#define SWSCI_SBCB_SET_SPREAD_SPECTRUM	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
226
#define SWSCI_SBCB_SET_SPREAD_SPECTRUM	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
229
#define SWSCI_SBCB_POST_VBE_PM		SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
227
#define SWSCI_SBCB_POST_VBE_PM		SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
230
#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
228
#define SWSCI_SBCB_ENABLE_DISABLE_AUDIO	SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
231
 
229
 
232
#define ACPI_OTHER_OUTPUT (0<<8)
230
#define ACPI_OTHER_OUTPUT (0<<8)
233
#define ACPI_VGA_OUTPUT (1<<8)
231
#define ACPI_VGA_OUTPUT (1<<8)
234
#define ACPI_TV_OUTPUT (2<<8)
232
#define ACPI_TV_OUTPUT (2<<8)
235
#define ACPI_DIGITAL_OUTPUT (3<<8)
233
#define ACPI_DIGITAL_OUTPUT (3<<8)
236
#define ACPI_LVDS_OUTPUT (4<<8)
234
#define ACPI_LVDS_OUTPUT (4<<8)
237
 
235
 
238
#define MAX_DSLP	1500
236
#define MAX_DSLP	1500
239
 
237
 
240
#ifdef CONFIG_ACPI
238
#ifdef CONFIG_ACPI
241
static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
239
static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
242
{
240
{
243
	struct drm_i915_private *dev_priv = dev->dev_private;
241
	struct drm_i915_private *dev_priv = dev->dev_private;
244
	struct opregion_swsci *swsci = dev_priv->opregion.swsci;
242
	struct opregion_swsci *swsci = dev_priv->opregion.swsci;
245
	u32 main_function, sub_function, scic;
243
	u32 main_function, sub_function, scic;
246
	u16 pci_swsci;
244
	u16 pci_swsci;
247
	u32 dslp;
245
	u32 dslp;
248
 
246
 
249
	if (!swsci)
247
	if (!swsci)
250
		return -ENODEV;
248
		return -ENODEV;
251
 
249
 
252
	main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >>
250
	main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >>
253
		SWSCI_SCIC_MAIN_FUNCTION_SHIFT;
251
		SWSCI_SCIC_MAIN_FUNCTION_SHIFT;
254
	sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >>
252
	sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >>
255
		SWSCI_SCIC_SUB_FUNCTION_SHIFT;
253
		SWSCI_SCIC_SUB_FUNCTION_SHIFT;
256
 
254
 
257
	/* Check if we can call the function. See swsci_setup for details. */
255
	/* Check if we can call the function. See swsci_setup for details. */
258
	if (main_function == SWSCI_SBCB) {
256
	if (main_function == SWSCI_SBCB) {
259
		if ((dev_priv->opregion.swsci_sbcb_sub_functions &
257
		if ((dev_priv->opregion.swsci_sbcb_sub_functions &
260
		     (1 << sub_function)) == 0)
258
		     (1 << sub_function)) == 0)
261
			return -EINVAL;
259
			return -EINVAL;
262
	} else if (main_function == SWSCI_GBDA) {
260
	} else if (main_function == SWSCI_GBDA) {
263
		if ((dev_priv->opregion.swsci_gbda_sub_functions &
261
		if ((dev_priv->opregion.swsci_gbda_sub_functions &
264
		     (1 << sub_function)) == 0)
262
		     (1 << sub_function)) == 0)
265
			return -EINVAL;
263
			return -EINVAL;
266
	}
264
	}
267
 
265
 
268
	/* Driver sleep timeout in ms. */
266
	/* Driver sleep timeout in ms. */
269
	dslp = swsci->dslp;
267
	dslp = swsci->dslp;
270
	if (!dslp) {
268
	if (!dslp) {
271
		/* The spec says 2ms should be the default, but it's too small
269
		/* The spec says 2ms should be the default, but it's too small
272
		 * for some machines. */
270
		 * for some machines. */
273
		dslp = 50;
271
		dslp = 50;
274
	} else if (dslp > MAX_DSLP) {
272
	} else if (dslp > MAX_DSLP) {
275
		/* Hey bios, trust must be earned. */
273
		/* Hey bios, trust must be earned. */
276
		DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, "
274
		DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, "
277
			      "using %u ms instead\n", dslp, MAX_DSLP);
275
			      "using %u ms instead\n", dslp, MAX_DSLP);
278
		dslp = MAX_DSLP;
276
		dslp = MAX_DSLP;
279
	}
277
	}
280
 
278
 
281
	/* The spec tells us to do this, but we are the only user... */
279
	/* The spec tells us to do this, but we are the only user... */
282
	scic = swsci->scic;
280
	scic = swsci->scic;
283
	if (scic & SWSCI_SCIC_INDICATOR) {
281
	if (scic & SWSCI_SCIC_INDICATOR) {
284
		DRM_DEBUG_DRIVER("SWSCI request already in progress\n");
282
		DRM_DEBUG_DRIVER("SWSCI request already in progress\n");
285
		return -EBUSY;
283
		return -EBUSY;
286
	}
284
	}
287
 
285
 
288
	scic = function | SWSCI_SCIC_INDICATOR;
286
	scic = function | SWSCI_SCIC_INDICATOR;
289
 
287
 
290
	swsci->parm = parm;
288
	swsci->parm = parm;
291
	swsci->scic = scic;
289
	swsci->scic = scic;
292
 
290
 
293
	/* Ensure SCI event is selected and event trigger is cleared. */
291
	/* Ensure SCI event is selected and event trigger is cleared. */
294
	pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci);
292
	pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci);
295
	if (!(pci_swsci & PCI_SWSCI_SCISEL) || (pci_swsci & PCI_SWSCI_GSSCIE)) {
293
	if (!(pci_swsci & PCI_SWSCI_SCISEL) || (pci_swsci & PCI_SWSCI_GSSCIE)) {
296
		pci_swsci |= PCI_SWSCI_SCISEL;
294
		pci_swsci |= PCI_SWSCI_SCISEL;
297
		pci_swsci &= ~PCI_SWSCI_GSSCIE;
295
		pci_swsci &= ~PCI_SWSCI_GSSCIE;
298
		pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
296
		pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
299
	}
297
	}
300
 
298
 
301
	/* Use event trigger to tell bios to check the mail. */
299
	/* Use event trigger to tell bios to check the mail. */
302
	pci_swsci |= PCI_SWSCI_GSSCIE;
300
	pci_swsci |= PCI_SWSCI_GSSCIE;
303
	pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
301
	pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
304
 
302
 
305
	/* Poll for the result. */
303
	/* Poll for the result. */
306
#define C (((scic = swsci->scic) & SWSCI_SCIC_INDICATOR) == 0)
304
#define C (((scic = swsci->scic) & SWSCI_SCIC_INDICATOR) == 0)
307
	if (wait_for(C, dslp)) {
305
	if (wait_for(C, dslp)) {
308
		DRM_DEBUG_DRIVER("SWSCI request timed out\n");
306
		DRM_DEBUG_DRIVER("SWSCI request timed out\n");
309
		return -ETIMEDOUT;
307
		return -ETIMEDOUT;
310
	}
308
	}
311
 
309
 
312
	scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >>
310
	scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >>
313
		SWSCI_SCIC_EXIT_STATUS_SHIFT;
311
		SWSCI_SCIC_EXIT_STATUS_SHIFT;
314
 
312
 
315
	/* Note: scic == 0 is an error! */
313
	/* Note: scic == 0 is an error! */
316
	if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) {
314
	if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) {
317
		DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic);
315
		DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic);
318
		return -EIO;
316
		return -EIO;
319
	}
317
	}
320
 
318
 
321
	if (parm_out)
319
	if (parm_out)
322
		*parm_out = swsci->parm;
320
		*parm_out = swsci->parm;
323
 
321
 
324
	return 0;
322
	return 0;
325
 
323
 
326
#undef C
324
#undef C
327
}
325
}
328
 
326
 
329
#define DISPLAY_TYPE_CRT			0
327
#define DISPLAY_TYPE_CRT			0
330
#define DISPLAY_TYPE_TV				1
328
#define DISPLAY_TYPE_TV				1
331
#define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL	2
329
#define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL	2
332
#define DISPLAY_TYPE_INTERNAL_FLAT_PANEL	3
330
#define DISPLAY_TYPE_INTERNAL_FLAT_PANEL	3
333
 
331
 
334
int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
332
int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
335
				  bool enable)
333
				  bool enable)
336
{
334
{
337
	struct drm_device *dev = intel_encoder->base.dev;
335
	struct drm_device *dev = intel_encoder->base.dev;
338
	u32 parm = 0;
336
	u32 parm = 0;
339
	u32 type = 0;
337
	u32 type = 0;
340
	u32 port;
338
	u32 port;
341
 
339
 
342
	/* don't care about old stuff for now */
340
	/* don't care about old stuff for now */
343
	if (!HAS_DDI(dev))
341
	if (!HAS_DDI(dev))
344
		return 0;
342
		return 0;
345
 
343
 
346
	if (intel_encoder->type == INTEL_OUTPUT_DSI)
344
	if (intel_encoder->type == INTEL_OUTPUT_DSI)
347
		port = 0;
345
		port = 0;
348
	else
346
	else
349
		port = intel_ddi_get_encoder_port(intel_encoder);
347
		port = intel_ddi_get_encoder_port(intel_encoder);
350
 
348
 
351
	if (port == PORT_E)  {
349
	if (port == PORT_E)  {
352
		port = 0;
350
		port = 0;
353
	} else {
351
	} else {
354
		parm |= 1 << port;
352
		parm |= 1 << port;
355
		port++;
353
		port++;
356
	}
354
	}
357
 
355
 
358
	if (!enable)
356
	if (!enable)
359
		parm |= 4 << 8;
357
		parm |= 4 << 8;
360
 
358
 
361
	switch (intel_encoder->type) {
359
	switch (intel_encoder->type) {
362
	case INTEL_OUTPUT_ANALOG:
360
	case INTEL_OUTPUT_ANALOG:
363
		type = DISPLAY_TYPE_CRT;
361
		type = DISPLAY_TYPE_CRT;
364
		break;
362
		break;
365
	case INTEL_OUTPUT_UNKNOWN:
363
	case INTEL_OUTPUT_UNKNOWN:
366
	case INTEL_OUTPUT_DISPLAYPORT:
364
	case INTEL_OUTPUT_DISPLAYPORT:
367
	case INTEL_OUTPUT_HDMI:
365
	case INTEL_OUTPUT_HDMI:
368
	case INTEL_OUTPUT_DP_MST:
366
	case INTEL_OUTPUT_DP_MST:
369
		type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
367
		type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
370
		break;
368
		break;
371
	case INTEL_OUTPUT_EDP:
369
	case INTEL_OUTPUT_EDP:
372
	case INTEL_OUTPUT_DSI:
370
	case INTEL_OUTPUT_DSI:
373
		type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL;
371
		type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL;
374
		break;
372
		break;
375
	default:
373
	default:
376
		WARN_ONCE(1, "unsupported intel_encoder type %d\n",
374
		WARN_ONCE(1, "unsupported intel_encoder type %d\n",
377
			  intel_encoder->type);
375
			  intel_encoder->type);
378
		return -EINVAL;
376
		return -EINVAL;
379
	}
377
	}
380
 
378
 
381
	parm |= type << (16 + port * 3);
379
	parm |= type << (16 + port * 3);
382
 
380
 
383
	return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL);
381
	return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL);
384
}
382
}
385
 
383
 
386
static const struct {
384
static const struct {
387
	pci_power_t pci_power_state;
385
	pci_power_t pci_power_state;
388
	u32 parm;
386
	u32 parm;
389
} power_state_map[] = {
387
} power_state_map[] = {
390
	{ PCI_D0,	0x00 },
388
	{ PCI_D0,	0x00 },
391
	{ PCI_D1,	0x01 },
389
	{ PCI_D1,	0x01 },
392
	{ PCI_D2,	0x02 },
390
	{ PCI_D2,	0x02 },
393
	{ PCI_D3hot,	0x04 },
391
	{ PCI_D3hot,	0x04 },
394
	{ PCI_D3cold,	0x04 },
392
	{ PCI_D3cold,	0x04 },
395
};
393
};
396
 
394
 
397
int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
395
int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
398
{
396
{
399
	int i;
397
	int i;
400
 
398
 
401
	if (!HAS_DDI(dev))
399
	if (!HAS_DDI(dev))
402
		return 0;
400
		return 0;
403
 
401
 
404
	for (i = 0; i < ARRAY_SIZE(power_state_map); i++) {
402
	for (i = 0; i < ARRAY_SIZE(power_state_map); i++) {
405
		if (state == power_state_map[i].pci_power_state)
403
		if (state == power_state_map[i].pci_power_state)
406
			return swsci(dev, SWSCI_SBCB_ADAPTER_POWER_STATE,
404
			return swsci(dev, SWSCI_SBCB_ADAPTER_POWER_STATE,
407
				     power_state_map[i].parm, NULL);
405
				     power_state_map[i].parm, NULL);
408
	}
406
	}
409
 
407
 
410
	return -EINVAL;
408
	return -EINVAL;
411
}
409
}
412
 
410
 
413
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
411
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
414
{
412
{
415
	struct drm_i915_private *dev_priv = dev->dev_private;
413
	struct drm_i915_private *dev_priv = dev->dev_private;
416
	struct intel_connector *intel_connector;
414
	struct intel_connector *intel_connector;
417
	struct opregion_asle *asle = dev_priv->opregion.asle;
415
	struct opregion_asle *asle = dev_priv->opregion.asle;
418
 
416
 
419
	DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
417
	DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
420
 
418
 
421
	if (acpi_video_get_backlight_type() == acpi_backlight_native) {
419
	if (acpi_video_get_backlight_type() == acpi_backlight_native) {
422
		DRM_DEBUG_KMS("opregion backlight request ignored\n");
420
		DRM_DEBUG_KMS("opregion backlight request ignored\n");
423
		return 0;
421
		return 0;
424
	}
422
	}
425
 
423
 
426
	if (!(bclp & ASLE_BCLP_VALID))
424
	if (!(bclp & ASLE_BCLP_VALID))
427
		return ASLC_BACKLIGHT_FAILED;
425
		return ASLC_BACKLIGHT_FAILED;
428
 
426
 
429
	bclp &= ASLE_BCLP_MSK;
427
	bclp &= ASLE_BCLP_MSK;
430
	if (bclp > 255)
428
	if (bclp > 255)
431
		return ASLC_BACKLIGHT_FAILED;
429
		return ASLC_BACKLIGHT_FAILED;
432
 
430
 
433
	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
431
	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
434
 
432
 
435
	/*
433
	/*
436
	 * Update backlight on all connectors that support backlight (usually
434
	 * Update backlight on all connectors that support backlight (usually
437
	 * only one).
435
	 * only one).
438
	 */
436
	 */
439
	DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
437
	DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
440
	list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
438
	list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
441
		intel_panel_set_backlight_acpi(intel_connector, bclp, 255);
439
		intel_panel_set_backlight_acpi(intel_connector, bclp, 255);
442
	asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
440
	asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
443
 
441
 
444
	drm_modeset_unlock(&dev->mode_config.connection_mutex);
442
	drm_modeset_unlock(&dev->mode_config.connection_mutex);
445
 
443
 
446
 
444
 
447
	return 0;
445
	return 0;
448
}
446
}
449
 
447
 
450
static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
448
static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
451
{
449
{
452
	/* alsi is the current ALS reading in lux. 0 indicates below sensor
450
	/* alsi is the current ALS reading in lux. 0 indicates below sensor
453
	   range, 0xffff indicates above sensor range. 1-0xfffe are valid */
451
	   range, 0xffff indicates above sensor range. 1-0xfffe are valid */
454
	DRM_DEBUG_DRIVER("Illum is not supported\n");
452
	DRM_DEBUG_DRIVER("Illum is not supported\n");
455
	return ASLC_ALS_ILLUM_FAILED;
453
	return ASLC_ALS_ILLUM_FAILED;
456
}
454
}
457
 
455
 
458
static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
456
static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
459
{
457
{
460
	DRM_DEBUG_DRIVER("PWM freq is not supported\n");
458
	DRM_DEBUG_DRIVER("PWM freq is not supported\n");
461
	return ASLC_PWM_FREQ_FAILED;
459
	return ASLC_PWM_FREQ_FAILED;
462
}
460
}
463
 
461
 
464
static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
462
static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
465
{
463
{
466
	/* Panel fitting is currently controlled by the X code, so this is a
464
	/* Panel fitting is currently controlled by the X code, so this is a
467
	   noop until modesetting support works fully */
465
	   noop until modesetting support works fully */
468
	DRM_DEBUG_DRIVER("Pfit is not supported\n");
466
	DRM_DEBUG_DRIVER("Pfit is not supported\n");
469
	return ASLC_PFIT_FAILED;
467
	return ASLC_PFIT_FAILED;
470
}
468
}
471
 
469
 
472
static u32 asle_set_supported_rotation_angles(struct drm_device *dev, u32 srot)
470
static u32 asle_set_supported_rotation_angles(struct drm_device *dev, u32 srot)
473
{
471
{
474
	DRM_DEBUG_DRIVER("SROT is not supported\n");
472
	DRM_DEBUG_DRIVER("SROT is not supported\n");
475
	return ASLC_ROTATION_ANGLES_FAILED;
473
	return ASLC_ROTATION_ANGLES_FAILED;
476
}
474
}
477
 
475
 
478
static u32 asle_set_button_array(struct drm_device *dev, u32 iuer)
476
static u32 asle_set_button_array(struct drm_device *dev, u32 iuer)
479
{
477
{
480
	if (!iuer)
478
	if (!iuer)
481
		DRM_DEBUG_DRIVER("Button array event is not supported (nothing)\n");
479
		DRM_DEBUG_DRIVER("Button array event is not supported (nothing)\n");
482
	if (iuer & ASLE_IUER_ROTATION_LOCK_BTN)
480
	if (iuer & ASLE_IUER_ROTATION_LOCK_BTN)
483
		DRM_DEBUG_DRIVER("Button array event is not supported (rotation lock)\n");
481
		DRM_DEBUG_DRIVER("Button array event is not supported (rotation lock)\n");
484
	if (iuer & ASLE_IUER_VOLUME_DOWN_BTN)
482
	if (iuer & ASLE_IUER_VOLUME_DOWN_BTN)
485
		DRM_DEBUG_DRIVER("Button array event is not supported (volume down)\n");
483
		DRM_DEBUG_DRIVER("Button array event is not supported (volume down)\n");
486
	if (iuer & ASLE_IUER_VOLUME_UP_BTN)
484
	if (iuer & ASLE_IUER_VOLUME_UP_BTN)
487
		DRM_DEBUG_DRIVER("Button array event is not supported (volume up)\n");
485
		DRM_DEBUG_DRIVER("Button array event is not supported (volume up)\n");
488
	if (iuer & ASLE_IUER_WINDOWS_BTN)
486
	if (iuer & ASLE_IUER_WINDOWS_BTN)
489
		DRM_DEBUG_DRIVER("Button array event is not supported (windows)\n");
487
		DRM_DEBUG_DRIVER("Button array event is not supported (windows)\n");
490
	if (iuer & ASLE_IUER_POWER_BTN)
488
	if (iuer & ASLE_IUER_POWER_BTN)
491
		DRM_DEBUG_DRIVER("Button array event is not supported (power)\n");
489
		DRM_DEBUG_DRIVER("Button array event is not supported (power)\n");
492
 
490
 
493
	return ASLC_BUTTON_ARRAY_FAILED;
491
	return ASLC_BUTTON_ARRAY_FAILED;
494
}
492
}
495
 
493
 
496
static u32 asle_set_convertible(struct drm_device *dev, u32 iuer)
494
static u32 asle_set_convertible(struct drm_device *dev, u32 iuer)
497
{
495
{
498
	if (iuer & ASLE_IUER_CONVERTIBLE)
496
	if (iuer & ASLE_IUER_CONVERTIBLE)
499
		DRM_DEBUG_DRIVER("Convertible is not supported (clamshell)\n");
497
		DRM_DEBUG_DRIVER("Convertible is not supported (clamshell)\n");
500
	else
498
	else
501
		DRM_DEBUG_DRIVER("Convertible is not supported (slate)\n");
499
		DRM_DEBUG_DRIVER("Convertible is not supported (slate)\n");
502
 
500
 
503
	return ASLC_CONVERTIBLE_FAILED;
501
	return ASLC_CONVERTIBLE_FAILED;
504
}
502
}
505
 
503
 
506
static u32 asle_set_docking(struct drm_device *dev, u32 iuer)
504
static u32 asle_set_docking(struct drm_device *dev, u32 iuer)
507
{
505
{
508
	if (iuer & ASLE_IUER_DOCKING)
506
	if (iuer & ASLE_IUER_DOCKING)
509
		DRM_DEBUG_DRIVER("Docking is not supported (docked)\n");
507
		DRM_DEBUG_DRIVER("Docking is not supported (docked)\n");
510
	else
508
	else
511
		DRM_DEBUG_DRIVER("Docking is not supported (undocked)\n");
509
		DRM_DEBUG_DRIVER("Docking is not supported (undocked)\n");
512
 
510
 
513
	return ASLC_DOCKING_FAILED;
511
	return ASLC_DOCKING_FAILED;
514
}
512
}
515
 
513
 
516
static u32 asle_isct_state(struct drm_device *dev)
514
static u32 asle_isct_state(struct drm_device *dev)
517
{
515
{
518
	DRM_DEBUG_DRIVER("ISCT is not supported\n");
516
	DRM_DEBUG_DRIVER("ISCT is not supported\n");
519
	return ASLC_ISCT_STATE_FAILED;
517
	return ASLC_ISCT_STATE_FAILED;
520
}
518
}
521
 
519
 
522
static void asle_work(struct work_struct *work)
520
static void asle_work(struct work_struct *work)
523
{
521
{
524
	struct intel_opregion *opregion =
522
	struct intel_opregion *opregion =
525
		container_of(work, struct intel_opregion, asle_work);
523
		container_of(work, struct intel_opregion, asle_work);
526
	struct drm_i915_private *dev_priv =
524
	struct drm_i915_private *dev_priv =
527
		container_of(opregion, struct drm_i915_private, opregion);
525
		container_of(opregion, struct drm_i915_private, opregion);
528
	struct drm_device *dev = dev_priv->dev;
526
	struct drm_device *dev = dev_priv->dev;
529
	struct opregion_asle *asle = dev_priv->opregion.asle;
527
	struct opregion_asle *asle = dev_priv->opregion.asle;
530
	u32 aslc_stat = 0;
528
	u32 aslc_stat = 0;
531
	u32 aslc_req;
529
	u32 aslc_req;
532
 
530
 
533
	if (!asle)
531
	if (!asle)
534
		return;
532
		return;
535
 
533
 
536
	aslc_req = asle->aslc;
534
	aslc_req = asle->aslc;
537
 
535
 
538
	if (!(aslc_req & ASLC_REQ_MSK)) {
536
	if (!(aslc_req & ASLC_REQ_MSK)) {
539
		DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n",
537
		DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n",
540
				 aslc_req);
538
				 aslc_req);
541
		return;
539
		return;
542
	}
540
	}
543
 
541
 
544
	if (aslc_req & ASLC_SET_ALS_ILLUM)
542
	if (aslc_req & ASLC_SET_ALS_ILLUM)
545
		aslc_stat |= asle_set_als_illum(dev, asle->alsi);
543
		aslc_stat |= asle_set_als_illum(dev, asle->alsi);
546
 
544
 
547
	if (aslc_req & ASLC_SET_BACKLIGHT)
545
	if (aslc_req & ASLC_SET_BACKLIGHT)
548
		aslc_stat |= asle_set_backlight(dev, asle->bclp);
546
		aslc_stat |= asle_set_backlight(dev, asle->bclp);
549
 
547
 
550
	if (aslc_req & ASLC_SET_PFIT)
548
	if (aslc_req & ASLC_SET_PFIT)
551
		aslc_stat |= asle_set_pfit(dev, asle->pfit);
549
		aslc_stat |= asle_set_pfit(dev, asle->pfit);
552
 
550
 
553
	if (aslc_req & ASLC_SET_PWM_FREQ)
551
	if (aslc_req & ASLC_SET_PWM_FREQ)
554
		aslc_stat |= asle_set_pwm_freq(dev, asle->pfmb);
552
		aslc_stat |= asle_set_pwm_freq(dev, asle->pfmb);
555
 
553
 
556
	if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES)
554
	if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES)
557
		aslc_stat |= asle_set_supported_rotation_angles(dev,
555
		aslc_stat |= asle_set_supported_rotation_angles(dev,
558
							asle->srot);
556
							asle->srot);
559
 
557
 
560
	if (aslc_req & ASLC_BUTTON_ARRAY)
558
	if (aslc_req & ASLC_BUTTON_ARRAY)
561
		aslc_stat |= asle_set_button_array(dev, asle->iuer);
559
		aslc_stat |= asle_set_button_array(dev, asle->iuer);
562
 
560
 
563
	if (aslc_req & ASLC_CONVERTIBLE_INDICATOR)
561
	if (aslc_req & ASLC_CONVERTIBLE_INDICATOR)
564
		aslc_stat |= asle_set_convertible(dev, asle->iuer);
562
		aslc_stat |= asle_set_convertible(dev, asle->iuer);
565
 
563
 
566
	if (aslc_req & ASLC_DOCKING_INDICATOR)
564
	if (aslc_req & ASLC_DOCKING_INDICATOR)
567
		aslc_stat |= asle_set_docking(dev, asle->iuer);
565
		aslc_stat |= asle_set_docking(dev, asle->iuer);
568
 
566
 
569
	if (aslc_req & ASLC_ISCT_STATE_CHANGE)
567
	if (aslc_req & ASLC_ISCT_STATE_CHANGE)
570
		aslc_stat |= asle_isct_state(dev);
568
		aslc_stat |= asle_isct_state(dev);
571
 
569
 
572
	asle->aslc = aslc_stat;
570
	asle->aslc = aslc_stat;
573
}
571
}
574
 
572
 
575
void intel_opregion_asle_intr(struct drm_device *dev)
573
void intel_opregion_asle_intr(struct drm_device *dev)
576
{
574
{
577
	struct drm_i915_private *dev_priv = dev->dev_private;
575
	struct drm_i915_private *dev_priv = dev->dev_private;
578
 
576
 
579
	if (dev_priv->opregion.asle)
577
	if (dev_priv->opregion.asle)
580
		schedule_work(&dev_priv->opregion.asle_work);
578
		schedule_work(&dev_priv->opregion.asle_work);
581
}
579
}
582
 
580
 
583
#define ACPI_EV_DISPLAY_SWITCH (1<<0)
581
#define ACPI_EV_DISPLAY_SWITCH (1<<0)
584
#define ACPI_EV_LID            (1<<1)
582
#define ACPI_EV_LID            (1<<1)
585
#define ACPI_EV_DOCK           (1<<2)
583
#define ACPI_EV_DOCK           (1<<2)
586
 
584
 
587
static struct intel_opregion *system_opregion;
585
static struct intel_opregion *system_opregion;
588
 
586
 
589
static int intel_opregion_video_event(struct notifier_block *nb,
587
static int intel_opregion_video_event(struct notifier_block *nb,
590
				      unsigned long val, void *data)
588
				      unsigned long val, void *data)
591
{
589
{
592
	/* The only video events relevant to opregion are 0x80. These indicate
590
	/* The only video events relevant to opregion are 0x80. These indicate
593
	   either a docking event, lid switch or display switch request. In
591
	   either a docking event, lid switch or display switch request. In
594
	   Linux, these are handled by the dock, button and video drivers.
592
	   Linux, these are handled by the dock, button and video drivers.
595
	*/
593
	*/
596
 
594
 
597
	struct acpi_bus_event *event = data;
595
	struct acpi_bus_event *event = data;
598
	struct opregion_acpi *acpi;
596
	struct opregion_acpi *acpi;
599
	int ret = NOTIFY_OK;
597
	int ret = NOTIFY_OK;
600
 
598
 
601
	if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
599
	if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
602
		return NOTIFY_DONE;
600
		return NOTIFY_DONE;
603
 
601
 
604
	if (!system_opregion)
602
	if (!system_opregion)
605
		return NOTIFY_DONE;
603
		return NOTIFY_DONE;
606
 
604
 
607
	acpi = system_opregion->acpi;
605
	acpi = system_opregion->acpi;
608
 
606
 
609
	if (event->type == 0x80 && ((acpi->cevt & 1) == 0))
607
	if (event->type == 0x80 && ((acpi->cevt & 1) == 0))
610
		ret = NOTIFY_BAD;
608
		ret = NOTIFY_BAD;
611
 
609
 
612
	acpi->csts = 0;
610
	acpi->csts = 0;
613
 
611
 
614
	return ret;
612
	return ret;
615
}
613
}
616
 
614
 
617
static struct notifier_block intel_opregion_notifier = {
615
static struct notifier_block intel_opregion_notifier = {
618
	.notifier_call = intel_opregion_video_event,
616
	.notifier_call = intel_opregion_video_event,
619
};
617
};
620
 
618
 
621
/*
619
/*
622
 * Initialise the DIDL field in opregion. This passes a list of devices to
620
 * Initialise the DIDL field in opregion. This passes a list of devices to
623
 * the firmware. Values are defined by section B.4.2 of the ACPI specification
621
 * the firmware. Values are defined by section B.4.2 of the ACPI specification
624
 * (version 3)
622
 * (version 3)
625
 */
623
 */
626
 
624
 
627
static u32 get_did(struct intel_opregion *opregion, int i)
625
static u32 get_did(struct intel_opregion *opregion, int i)
628
{
626
{
629
	u32 did;
627
	u32 did;
630
 
628
 
631
	if (i < ARRAY_SIZE(opregion->acpi->didl)) {
629
	if (i < ARRAY_SIZE(opregion->acpi->didl)) {
632
		did = opregion->acpi->didl[i];
630
		did = opregion->acpi->didl[i];
633
	} else {
631
	} else {
634
		i -= ARRAY_SIZE(opregion->acpi->didl);
632
		i -= ARRAY_SIZE(opregion->acpi->didl);
635
 
633
 
636
		if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
634
		if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
637
			return 0;
635
			return 0;
638
 
636
 
639
		did = opregion->acpi->did2[i];
637
		did = opregion->acpi->did2[i];
640
	}
638
	}
641
 
639
 
642
	return did;
640
	return did;
643
}
641
}
644
 
642
 
645
static void set_did(struct intel_opregion *opregion, int i, u32 val)
643
static void set_did(struct intel_opregion *opregion, int i, u32 val)
646
{
644
{
647
	if (i < ARRAY_SIZE(opregion->acpi->didl)) {
645
	if (i < ARRAY_SIZE(opregion->acpi->didl)) {
648
		opregion->acpi->didl[i] = val;
646
		opregion->acpi->didl[i] = val;
649
	} else {
647
	} else {
650
		i -= ARRAY_SIZE(opregion->acpi->didl);
648
		i -= ARRAY_SIZE(opregion->acpi->didl);
651
 
649
 
652
		if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
650
		if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
653
			return;
651
			return;
654
 
652
 
655
		opregion->acpi->did2[i] = val;
653
		opregion->acpi->did2[i] = val;
656
	}
654
	}
657
}
655
}
658
 
656
 
659
static void intel_didl_outputs(struct drm_device *dev)
657
static void intel_didl_outputs(struct drm_device *dev)
660
{
658
{
661
	struct drm_i915_private *dev_priv = dev->dev_private;
659
	struct drm_i915_private *dev_priv = dev->dev_private;
662
	struct intel_opregion *opregion = &dev_priv->opregion;
660
	struct intel_opregion *opregion = &dev_priv->opregion;
663
	struct drm_connector *connector;
661
	struct drm_connector *connector;
664
	acpi_handle handle;
662
	acpi_handle handle;
665
	struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
663
	struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
666
	unsigned long long device_id;
664
	unsigned long long device_id;
667
	acpi_status status;
665
	acpi_status status;
668
	u32 temp, max_outputs;
666
	u32 temp, max_outputs;
669
	int i = 0;
667
	int i = 0;
670
 
668
 
671
	handle = ACPI_HANDLE(&dev->pdev->dev);
669
	handle = ACPI_HANDLE(&dev->pdev->dev);
672
	if (!handle || acpi_bus_get_device(handle, &acpi_dev))
670
	if (!handle || acpi_bus_get_device(handle, &acpi_dev))
673
		return;
671
		return;
674
 
672
 
675
	if (acpi_is_video_device(handle))
673
	if (acpi_is_video_device(handle))
676
		acpi_video_bus = acpi_dev;
674
		acpi_video_bus = acpi_dev;
677
	else {
675
	else {
678
		list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
676
		list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
679
			if (acpi_is_video_device(acpi_cdev->handle)) {
677
			if (acpi_is_video_device(acpi_cdev->handle)) {
680
				acpi_video_bus = acpi_cdev;
678
				acpi_video_bus = acpi_cdev;
681
				break;
679
				break;
682
			}
680
			}
683
		}
681
		}
684
	}
682
	}
685
 
683
 
686
	if (!acpi_video_bus) {
684
	if (!acpi_video_bus) {
687
		DRM_ERROR("No ACPI video bus found\n");
685
		DRM_ERROR("No ACPI video bus found\n");
688
		return;
686
		return;
689
	}
687
	}
690
 
688
 
691
	/*
689
	/*
692
	 * In theory, did2, the extended didl, gets added at opregion version
690
	 * In theory, did2, the extended didl, gets added at opregion version
693
	 * 3.0. In practice, however, we're supposed to set it for earlier
691
	 * 3.0. In practice, however, we're supposed to set it for earlier
694
	 * versions as well, since a BIOS that doesn't understand did2 should
692
	 * versions as well, since a BIOS that doesn't understand did2 should
695
	 * not look at it anyway. Use a variable so we can tweak this if a need
693
	 * not look at it anyway. Use a variable so we can tweak this if a need
696
	 * arises later.
694
	 * arises later.
697
	 */
695
	 */
698
	max_outputs = ARRAY_SIZE(opregion->acpi->didl) +
696
	max_outputs = ARRAY_SIZE(opregion->acpi->didl) +
699
		ARRAY_SIZE(opregion->acpi->did2);
697
		ARRAY_SIZE(opregion->acpi->did2);
700
 
698
 
701
	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
699
	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
702
		if (i >= max_outputs) {
700
		if (i >= max_outputs) {
703
			DRM_DEBUG_KMS("More than %u outputs detected via ACPI\n",
701
			DRM_DEBUG_KMS("More than %u outputs detected via ACPI\n",
704
				      max_outputs);
702
				      max_outputs);
705
			return;
703
			return;
706
		}
704
		}
707
		status = acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
705
		status = acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
708
					       NULL, &device_id);
706
					       NULL, &device_id);
709
		if (ACPI_SUCCESS(status)) {
707
		if (ACPI_SUCCESS(status)) {
710
			if (!device_id)
708
			if (!device_id)
711
				goto blind_set;
709
				goto blind_set;
712
			set_did(opregion, i++, (u32)(device_id & 0x0f0f));
710
			set_did(opregion, i++, (u32)(device_id & 0x0f0f));
713
		}
711
		}
714
	}
712
	}
715
 
713
 
716
end:
714
end:
717
	DRM_DEBUG_KMS("%d outputs detected\n", i);
715
	DRM_DEBUG_KMS("%d outputs detected\n", i);
718
 
716
 
719
	/* If fewer than max outputs, the list must be null terminated */
717
	/* If fewer than max outputs, the list must be null terminated */
720
	if (i < max_outputs)
718
	if (i < max_outputs)
721
		set_did(opregion, i, 0);
719
		set_did(opregion, i, 0);
722
	return;
720
	return;
723
 
721
 
724
blind_set:
722
blind_set:
725
	i = 0;
723
	i = 0;
726
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
724
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
727
		int output_type = ACPI_OTHER_OUTPUT;
725
		int output_type = ACPI_OTHER_OUTPUT;
728
		if (i >= max_outputs) {
726
		if (i >= max_outputs) {
729
			DRM_DEBUG_KMS("More than %u outputs in connector list\n",
727
			DRM_DEBUG_KMS("More than %u outputs in connector list\n",
730
				      max_outputs);
728
				      max_outputs);
731
			return;
729
			return;
732
		}
730
		}
733
		switch (connector->connector_type) {
731
		switch (connector->connector_type) {
734
		case DRM_MODE_CONNECTOR_VGA:
732
		case DRM_MODE_CONNECTOR_VGA:
735
		case DRM_MODE_CONNECTOR_DVIA:
733
		case DRM_MODE_CONNECTOR_DVIA:
736
			output_type = ACPI_VGA_OUTPUT;
734
			output_type = ACPI_VGA_OUTPUT;
737
			break;
735
			break;
738
		case DRM_MODE_CONNECTOR_Composite:
736
		case DRM_MODE_CONNECTOR_Composite:
739
		case DRM_MODE_CONNECTOR_SVIDEO:
737
		case DRM_MODE_CONNECTOR_SVIDEO:
740
		case DRM_MODE_CONNECTOR_Component:
738
		case DRM_MODE_CONNECTOR_Component:
741
		case DRM_MODE_CONNECTOR_9PinDIN:
739
		case DRM_MODE_CONNECTOR_9PinDIN:
742
			output_type = ACPI_TV_OUTPUT;
740
			output_type = ACPI_TV_OUTPUT;
743
			break;
741
			break;
744
		case DRM_MODE_CONNECTOR_DVII:
742
		case DRM_MODE_CONNECTOR_DVII:
745
		case DRM_MODE_CONNECTOR_DVID:
743
		case DRM_MODE_CONNECTOR_DVID:
746
		case DRM_MODE_CONNECTOR_DisplayPort:
744
		case DRM_MODE_CONNECTOR_DisplayPort:
747
		case DRM_MODE_CONNECTOR_HDMIA:
745
		case DRM_MODE_CONNECTOR_HDMIA:
748
		case DRM_MODE_CONNECTOR_HDMIB:
746
		case DRM_MODE_CONNECTOR_HDMIB:
749
			output_type = ACPI_DIGITAL_OUTPUT;
747
			output_type = ACPI_DIGITAL_OUTPUT;
750
			break;
748
			break;
751
		case DRM_MODE_CONNECTOR_LVDS:
749
		case DRM_MODE_CONNECTOR_LVDS:
752
			output_type = ACPI_LVDS_OUTPUT;
750
			output_type = ACPI_LVDS_OUTPUT;
753
			break;
751
			break;
754
		}
752
		}
755
		temp = get_did(opregion, i);
753
		temp = get_did(opregion, i);
756
		set_did(opregion, i, temp | (1 << 31) | output_type | i);
754
		set_did(opregion, i, temp | (1 << 31) | output_type | i);
757
		i++;
755
		i++;
758
	}
756
	}
759
	goto end;
757
	goto end;
760
}
758
}
761
 
759
 
762
static void intel_setup_cadls(struct drm_device *dev)
760
static void intel_setup_cadls(struct drm_device *dev)
763
{
761
{
764
	struct drm_i915_private *dev_priv = dev->dev_private;
762
	struct drm_i915_private *dev_priv = dev->dev_private;
765
	struct intel_opregion *opregion = &dev_priv->opregion;
763
	struct intel_opregion *opregion = &dev_priv->opregion;
766
	int i = 0;
764
	int i = 0;
767
	u32 disp_id;
765
	u32 disp_id;
768
 
766
 
769
	/* Initialize the CADL field by duplicating the DIDL values.
767
	/* Initialize the CADL field by duplicating the DIDL values.
770
	 * Technically, this is not always correct as display outputs may exist,
768
	 * Technically, this is not always correct as display outputs may exist,
771
	 * but not active. This initialization is necessary for some Clevo
769
	 * but not active. This initialization is necessary for some Clevo
772
	 * laptops that check this field before processing the brightness and
770
	 * laptops that check this field before processing the brightness and
773
	 * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if
771
	 * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if
774
	 * there are less than eight devices. */
772
	 * there are less than eight devices. */
775
	do {
773
	do {
776
		disp_id = get_did(opregion, i);
774
		disp_id = get_did(opregion, i);
777
		opregion->acpi->cadl[i] = disp_id;
775
		opregion->acpi->cadl[i] = disp_id;
778
	} while (++i < 8 && disp_id != 0);
776
	} while (++i < 8 && disp_id != 0);
779
}
777
}
780
 
778
 
781
void intel_opregion_init(struct drm_device *dev)
779
void intel_opregion_init(struct drm_device *dev)
782
{
780
{
783
	struct drm_i915_private *dev_priv = dev->dev_private;
781
	struct drm_i915_private *dev_priv = dev->dev_private;
784
	struct intel_opregion *opregion = &dev_priv->opregion;
782
	struct intel_opregion *opregion = &dev_priv->opregion;
785
 
783
 
786
	if (!opregion->header)
784
	if (!opregion->header)
787
		return;
785
		return;
788
 
786
 
789
	if (opregion->acpi) {
787
	if (opregion->acpi) {
790
		intel_didl_outputs(dev);
788
		intel_didl_outputs(dev);
791
		intel_setup_cadls(dev);
789
		intel_setup_cadls(dev);
792
 
790
 
793
		/* Notify BIOS we are ready to handle ACPI video ext notifs.
791
		/* Notify BIOS we are ready to handle ACPI video ext notifs.
794
		 * Right now, all the events are handled by the ACPI video module.
792
		 * Right now, all the events are handled by the ACPI video module.
795
		 * We don't actually need to do anything with them. */
793
		 * We don't actually need to do anything with them. */
796
		opregion->acpi->csts = 0;
794
		opregion->acpi->csts = 0;
797
		opregion->acpi->drdy = 1;
795
		opregion->acpi->drdy = 1;
798
 
796
 
799
		system_opregion = opregion;
797
		system_opregion = opregion;
800
		register_acpi_notifier(&intel_opregion_notifier);
798
		register_acpi_notifier(&intel_opregion_notifier);
801
	}
799
	}
802
 
800
 
803
	if (opregion->asle) {
801
	if (opregion->asle) {
804
		opregion->asle->tche = ASLE_TCHE_BLC_EN;
802
		opregion->asle->tche = ASLE_TCHE_BLC_EN;
805
		opregion->asle->ardy = ASLE_ARDY_READY;
803
		opregion->asle->ardy = ASLE_ARDY_READY;
806
	}
804
	}
807
}
805
}
808
 
806
 
809
void intel_opregion_fini(struct drm_device *dev)
807
void intel_opregion_fini(struct drm_device *dev)
810
{
808
{
811
	struct drm_i915_private *dev_priv = dev->dev_private;
809
	struct drm_i915_private *dev_priv = dev->dev_private;
812
	struct intel_opregion *opregion = &dev_priv->opregion;
810
	struct intel_opregion *opregion = &dev_priv->opregion;
813
 
811
 
814
	if (!opregion->header)
812
	if (!opregion->header)
815
		return;
813
		return;
816
 
814
 
817
	if (opregion->asle)
815
	if (opregion->asle)
818
		opregion->asle->ardy = ASLE_ARDY_NOT_READY;
816
		opregion->asle->ardy = ASLE_ARDY_NOT_READY;
819
 
817
 
820
	cancel_work_sync(&dev_priv->opregion.asle_work);
818
	cancel_work_sync(&dev_priv->opregion.asle_work);
821
 
819
 
822
	if (opregion->acpi) {
820
	if (opregion->acpi) {
823
		opregion->acpi->drdy = 0;
821
		opregion->acpi->drdy = 0;
824
 
822
 
825
		system_opregion = NULL;
823
		system_opregion = NULL;
826
		unregister_acpi_notifier(&intel_opregion_notifier);
824
		unregister_acpi_notifier(&intel_opregion_notifier);
827
	}
825
	}
828
 
826
 
829
	/* just clear all opregion memory pointers now */
827
	/* just clear all opregion memory pointers now */
830
	memunmap(opregion->header);
828
	memunmap(opregion->header);
831
	opregion->header = NULL;
829
	opregion->header = NULL;
832
	opregion->acpi = NULL;
830
	opregion->acpi = NULL;
833
	opregion->swsci = NULL;
831
	opregion->swsci = NULL;
834
	opregion->asle = NULL;
832
	opregion->asle = NULL;
835
	opregion->vbt = NULL;
833
	opregion->vbt = NULL;
836
	opregion->lid_state = NULL;
834
	opregion->lid_state = NULL;
837
}
835
}
838
 
836
 
839
static void swsci_setup(struct drm_device *dev)
837
static void swsci_setup(struct drm_device *dev)
840
{
838
{
841
	struct drm_i915_private *dev_priv = dev->dev_private;
839
	struct drm_i915_private *dev_priv = dev->dev_private;
842
	struct intel_opregion *opregion = &dev_priv->opregion;
840
	struct intel_opregion *opregion = &dev_priv->opregion;
843
	bool requested_callbacks = false;
841
	bool requested_callbacks = false;
844
	u32 tmp;
842
	u32 tmp;
845
 
843
 
846
	/* Sub-function code 0 is okay, let's allow them. */
844
	/* Sub-function code 0 is okay, let's allow them. */
847
	opregion->swsci_gbda_sub_functions = 1;
845
	opregion->swsci_gbda_sub_functions = 1;
848
	opregion->swsci_sbcb_sub_functions = 1;
846
	opregion->swsci_sbcb_sub_functions = 1;
849
 
847
 
850
	/* We use GBDA to ask for supported GBDA calls. */
848
	/* We use GBDA to ask for supported GBDA calls. */
851
	if (swsci(dev, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) {
849
	if (swsci(dev, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) {
852
		/* make the bits match the sub-function codes */
850
		/* make the bits match the sub-function codes */
853
		tmp <<= 1;
851
		tmp <<= 1;
854
		opregion->swsci_gbda_sub_functions |= tmp;
852
		opregion->swsci_gbda_sub_functions |= tmp;
855
	}
853
	}
856
 
854
 
857
	/*
855
	/*
858
	 * We also use GBDA to ask for _requested_ SBCB callbacks. The driver
856
	 * We also use GBDA to ask for _requested_ SBCB callbacks. The driver
859
	 * must not call interfaces that are not specifically requested by the
857
	 * must not call interfaces that are not specifically requested by the
860
	 * bios.
858
	 * bios.
861
	 */
859
	 */
862
	if (swsci(dev, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) {
860
	if (swsci(dev, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) {
863
		/* here, the bits already match sub-function codes */
861
		/* here, the bits already match sub-function codes */
864
		opregion->swsci_sbcb_sub_functions |= tmp;
862
		opregion->swsci_sbcb_sub_functions |= tmp;
865
		requested_callbacks = true;
863
		requested_callbacks = true;
866
	}
864
	}
867
 
865
 
868
	/*
866
	/*
869
	 * But we use SBCB to ask for _supported_ SBCB calls. This does not mean
867
	 * But we use SBCB to ask for _supported_ SBCB calls. This does not mean
870
	 * the callback is _requested_. But we still can't call interfaces that
868
	 * the callback is _requested_. But we still can't call interfaces that
871
	 * are not requested.
869
	 * are not requested.
872
	 */
870
	 */
873
	if (swsci(dev, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) {
871
	if (swsci(dev, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) {
874
		/* make the bits match the sub-function codes */
872
		/* make the bits match the sub-function codes */
875
		u32 low = tmp & 0x7ff;
873
		u32 low = tmp & 0x7ff;
876
		u32 high = tmp & ~0xfff; /* bit 11 is reserved */
874
		u32 high = tmp & ~0xfff; /* bit 11 is reserved */
877
		tmp = (high << 4) | (low << 1) | 1;
875
		tmp = (high << 4) | (low << 1) | 1;
878
 
876
 
879
		/* best guess what to do with supported wrt requested */
877
		/* best guess what to do with supported wrt requested */
880
		if (requested_callbacks) {
878
		if (requested_callbacks) {
881
			u32 req = opregion->swsci_sbcb_sub_functions;
879
			u32 req = opregion->swsci_sbcb_sub_functions;
882
			if ((req & tmp) != req)
880
			if ((req & tmp) != req)
883
				DRM_DEBUG_DRIVER("SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", req, tmp);
881
				DRM_DEBUG_DRIVER("SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", req, tmp);
884
			/* XXX: for now, trust the requested callbacks */
882
			/* XXX: for now, trust the requested callbacks */
885
			/* opregion->swsci_sbcb_sub_functions &= tmp; */
883
			/* opregion->swsci_sbcb_sub_functions &= tmp; */
886
		} else {
884
		} else {
887
			opregion->swsci_sbcb_sub_functions |= tmp;
885
			opregion->swsci_sbcb_sub_functions |= tmp;
888
		}
886
		}
889
	}
887
	}
890
 
888
 
891
	DRM_DEBUG_DRIVER("SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n",
889
	DRM_DEBUG_DRIVER("SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n",
892
			 opregion->swsci_gbda_sub_functions,
890
			 opregion->swsci_gbda_sub_functions,
893
			 opregion->swsci_sbcb_sub_functions);
891
			 opregion->swsci_sbcb_sub_functions);
894
}
892
}
895
#else /* CONFIG_ACPI */
893
#else /* CONFIG_ACPI */
896
static inline void swsci_setup(struct drm_device *dev) {}
894
static inline void swsci_setup(struct drm_device *dev) {}
897
#endif  /* CONFIG_ACPI */
895
#endif  /* CONFIG_ACPI */
898
 
896
 
899
int intel_opregion_setup(struct drm_device *dev)
897
int intel_opregion_setup(struct drm_device *dev)
900
{
898
{
901
	struct drm_i915_private *dev_priv = dev->dev_private;
899
	struct drm_i915_private *dev_priv = dev->dev_private;
902
	struct intel_opregion *opregion = &dev_priv->opregion;
900
	struct intel_opregion *opregion = &dev_priv->opregion;
903
	u32 asls, mboxes;
901
	u32 asls, mboxes;
904
	char buf[sizeof(OPREGION_SIGNATURE)];
902
	char buf[sizeof(OPREGION_SIGNATURE)];
905
	int err = 0;
903
	int err = 0;
906
	void *base;
904
	void *base;
907
 
905
 
908
	BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
906
	BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
909
	BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
907
	BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
910
	BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100);
908
	BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100);
911
	BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100);
909
	BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100);
912
 
910
 
913
	pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
911
	pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
914
	DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
912
	DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
915
	if (asls == 0) {
913
	if (asls == 0) {
916
		DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
914
		DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
917
		return -ENOTSUPP;
915
		return -ENOTSUPP;
918
	}
916
	}
919
 
917
 
920
#ifdef CONFIG_ACPI
918
#ifdef CONFIG_ACPI
921
	INIT_WORK(&opregion->asle_work, asle_work);
919
	INIT_WORK(&opregion->asle_work, asle_work);
922
#endif
920
#endif
923
 
921
 
924
	base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB);
922
	base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB);
925
	if (!base)
923
	if (!base)
926
		return -ENOMEM;
924
		return -ENOMEM;
927
 
925
 
928
	memcpy(buf, base, sizeof(buf));
926
	memcpy(buf, base, sizeof(buf));
929
 
927
 
930
	if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
928
	if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
931
		DRM_DEBUG_DRIVER("opregion signature mismatch\n");
929
		DRM_DEBUG_DRIVER("opregion signature mismatch\n");
932
		err = -EINVAL;
930
		err = -EINVAL;
933
		goto err_out;
931
		goto err_out;
934
	}
932
	}
935
	opregion->header = base;
933
	opregion->header = base;
936
	opregion->vbt = base + OPREGION_VBT_OFFSET;
934
	opregion->vbt = base + OPREGION_VBT_OFFSET;
937
 
935
 
938
	opregion->lid_state = base + ACPI_CLID;
936
	opregion->lid_state = base + ACPI_CLID;
939
 
937
 
940
	mboxes = opregion->header->mboxes;
938
	mboxes = opregion->header->mboxes;
941
	if (mboxes & MBOX_ACPI) {
939
	if (mboxes & MBOX_ACPI) {
942
		DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
940
		DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
943
		opregion->acpi = base + OPREGION_ACPI_OFFSET;
941
		opregion->acpi = base + OPREGION_ACPI_OFFSET;
944
	}
942
	}
945
 
943
 
946
	if (mboxes & MBOX_SWSCI) {
944
	if (mboxes & MBOX_SWSCI) {
947
		DRM_DEBUG_DRIVER("SWSCI supported\n");
945
		DRM_DEBUG_DRIVER("SWSCI supported\n");
948
		opregion->swsci = base + OPREGION_SWSCI_OFFSET;
946
		opregion->swsci = base + OPREGION_SWSCI_OFFSET;
949
		swsci_setup(dev);
947
		swsci_setup(dev);
950
	}
948
	}
951
	if (mboxes & MBOX_ASLE) {
949
	if (mboxes & MBOX_ASLE) {
952
		DRM_DEBUG_DRIVER("ASLE supported\n");
950
		DRM_DEBUG_DRIVER("ASLE supported\n");
953
		opregion->asle = base + OPREGION_ASLE_OFFSET;
951
		opregion->asle = base + OPREGION_ASLE_OFFSET;
954
 
952
 
955
		opregion->asle->ardy = ASLE_ARDY_NOT_READY;
953
		opregion->asle->ardy = ASLE_ARDY_NOT_READY;
956
	}
954
	}
957
 
955
 
958
	return 0;
956
	return 0;
959
 
957
 
960
err_out:
958
err_out:
961
	memunmap(base);
959
	memunmap(base);
962
	return err;
960
	return err;
963
}
961
}
964
 
962
 
965
static>
963
static>
966
 
964
 
967
static>
965
static>
968
#define>
966
#define>
969
#define>
967
#define>
970
#define>
968
#define>
971
#define>
969
#define>
972
 
970
 
973
#define>
971
#define>
974
 
972
 
975
#define>
973
#define>
976
#define>
974
#define>
977
#define>
975
#define>
978
#define>
976
#define>
979
#define>
977
#define>
980
#define>
978
#define>
981
#define>
979
#define>
982
#define>
980
#define>
983
#define>
981
#define>
984
 
982
 
985
/*>
983
/*>
986
 
984
 
987
/*>
985
/*>
988
 
986
 
989
#define>
987
#define>
990
 
988
 
991
#define>
989
#define>
992
#define>
990
#define>
993
#define>
991
#define>
994
 
992
 
995
/*>
993
/*>
996
 
994
 
997
/*>
995
/*>
998
#define>
996
#define>
999
#define>
997
#define>
1000
#define>
998
#define>
1001
#define>
999
#define>
1002
#define>
1000
#define>
1003
#define>
1001
#define>
1004
 
1002
 
1005
/*>
1003
/*>
1006
 
1004
 
1007
/*>
1005
/*>
1008
#define>
1006
#define>
1009
#define>
1007
#define>
1010
 
1008
 
1011
struct>
1009
struct>
1012
 
1010
 
1013
struct>
1011
struct>
1014
#define>
1012
#define>
1015
#define>
1013
#define>
1016
#define>
1014
#define>
1017
#define>
1015
#define>
1018
#define>
1016
#define>
1019
#define>
1017
#define>