Subversion Repositories Kolibri OS

Rev

Rev 4104 | Rev 5060 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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