Subversion Repositories Kolibri OS

Rev

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

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