summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/i915_drv.h
blob: c10f5e59c819a06fa24a7c4d37bdc50f265caaad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
/* $OpenBSD: i915_drv.h,v 1.73 2012/09/25 10:19:46 jsg Exp $ */
/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
 */
/*
 *
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#ifndef _I915_DRV_H_
#define _I915_DRV_H_

#include "i915_reg.h"
#include "i915_drm.h"
#include "intel_bios.h"
#include "intel_ringbuffer.h"

#include <sys/workq.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>

/* General customization:
 */

#define DRIVER_AUTHOR		"Tungsten Graphics, Inc."

#define DRIVER_NAME		"i915"
#define DRIVER_DESC		"Intel Graphics"
#define DRIVER_DATE		"20080730"

enum pipe {
	PIPE_A = 0,
	PIPE_B,
	PIPE_C,
	I915_MAX_PIPES
};
#define pipe_name(p) ((p) + 'A')

enum transcoder {
	TRANSCODER_A = 0,
	TRANSCODER_B,
	TRANSCODER_C,
	TRANSCODER_EDP = 0xF,
};
#define transcoder_name(t) ((t) + 'A')

enum plane {
	PLANE_A = 0,
	PLANE_B,
	PLANE_C,
};
#define plane_name(p) ((p) + 'A')

enum port {
	PORT_A = 0,
	PORT_B,
	PORT_C,
	PORT_D,
	PORT_E,
	I915_MAX_PORTS
};
#define port_name(p) ((p) + 'A')

#define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++)

#define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \
	list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
		if ((intel_encoder)->base.crtc == (__crtc))

struct intel_pch_pll {
	int refcount; /* count of number of CRTCs sharing this PLL */
	int active; /* count of number of active CRTCs (i.e. DPMS on) */
	bool on; /* is the PLL actually active? Disabled during modeset */
	int pll_reg;
	int fp0_reg;
	int fp1_reg;
};
#define I915_NUM_PLLS 2

struct intel_ddi_plls {
	int spll_refcount;
	int wrpll1_refcount;
	int wrpll2_refcount;
};

/* Interface history:
 *
 * 1.1: Original.
 * 1.2: Add Power Management
 * 1.3: Add vblank support
 * 1.4: Fix cmdbuffer path, add heap destroy
 * 1.5: Add vblank pipe configuration
 * 1.6: - New ioctl for scheduling buffer swaps on vertical blank
 *      - Support vertical blank on secondary display pipe
 */
#define DRIVER_MAJOR		1
#define DRIVER_MINOR		6
#define DRIVER_PATCHLEVEL	0

#define I915_GEM_PHYS_CURSOR_0 1
#define I915_GEM_PHYS_CURSOR_1 2
#define I915_GEM_PHYS_OVERLAY_REGS 3
#define I915_MAX_PHYS_OBJECT (I915_GEM_PHYS_OVERLAY_REGS)

struct drm_i915_gem_phys_object {
	int id;
	struct drm_dmamem *handle;
	struct drm_i915_gem_object *cur_obj;
};

struct inteldrm_softc;

struct drm_i915_display_funcs {
	bool (*fbc_enabled)(struct drm_device *dev);
	void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
	void (*disable_fbc)(struct drm_device *dev);
	int (*get_display_clock_speed)(struct drm_device *dev);
	int (*get_fifo_size)(struct drm_device *dev, int plane);
	void (*update_wm)(struct drm_device *dev);
	void (*update_sprite_wm)(struct drm_device *dev, int pipe,
				 uint32_t sprite_width, int pixel_size);
	void (*update_linetime_wm)(struct drm_device *dev, int pipe,
				 struct drm_display_mode *mode);
	void (*modeset_global_resources)(struct drm_device *dev);
	int (*crtc_mode_set)(struct drm_crtc *crtc,
			     struct drm_display_mode *mode,
			     struct drm_display_mode *adjusted_mode,
			     int x, int y,
			     struct drm_framebuffer *old_fb);
	void (*crtc_enable)(struct drm_crtc *crtc);
	void (*crtc_disable)(struct drm_crtc *crtc);
	void (*off)(struct drm_crtc *crtc);
	void (*write_eld)(struct drm_connector *connector,
			  struct drm_crtc *crtc);
	void (*fdi_link_train)(struct drm_crtc *crtc);
	void (*init_clock_gating)(struct drm_device *dev);
	int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
			  struct drm_framebuffer *fb,
			  struct drm_i915_gem_object *obj);
	int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
			    int x, int y);
	/* clock updates for mode set */
	/* cursor updates */
	/* render clock increase/decrease */
	/* display clock increase/decrease */
	/* pll clock increase/decrease */
};

struct drm_i915_gt_funcs {
	void (*force_wake_get)(struct inteldrm_softc *dev_priv);
	void (*force_wake_put)(struct inteldrm_softc *dev_priv);
};

struct intel_device_info {
	u8 gen;
	u8 is_mobile:1;
	u8 is_i85x:1;
	u8 is_i915g:1;
	u8 is_i945gm:1;
	u8 is_g33:1;
	u8 need_gfx_hws:1;
	u8 is_g4x:1;
	u8 is_pineview:1;
	u8 is_broadwater:1;
	u8 is_crestline:1;
	u8 is_ivybridge:1;
	u8 is_valleyview:1;
	u8 has_force_wake:1;
	u8 is_haswell:1;
	u8 has_fbc:1;
	u8 has_pipe_cxsr:1;
	u8 has_hotplug:1;
	u8 cursor_needs_physical:1;
	u8 has_overlay:1;
	u8 overlay_needs_physical:1;
	u8 supports_tv:1;
	u8 has_bsd_ring:1;
	u8 has_blt_ring:1;
	u8 has_llc:1;
};

enum no_fbc_reason {
	FBC_NO_OUTPUT, /* no outputs enabled to compress */
	FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */
	FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */
	FBC_MODE_TOO_LARGE, /* mode too large for compression */
	FBC_BAD_PLANE, /* fbc not supported on plane */
	FBC_NOT_TILED, /* buffer not tiled */
	FBC_MULTIPLE_PIPES, /* more than one pipe active */
	FBC_MODULE_PARAM,
};

struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;

struct intel_opregion {
	struct opregion_header *header;
	struct opregion_acpi *acpi;
	struct opregion_swsci *swsci;
	struct opregion_asle *asle;
	void *vbt;
	u32 *lid_state;
};
#define OPREGION_SIZE            (8*1024)


#define I915_FENCE_REG_NONE -1
#define I915_MAX_NUM_FENCES 16

struct drm_i915_fence_reg {
	struct list_head lru_list;
	struct drm_i915_gem_object *obj;
	int pin_count;
};

struct sdvo_device_mapping {
	u8 initialized;
	u8 dvo_port;
	u8 slave_addr;
	u8 dvo_wiring;
	u8 i2c_pin;
	u8 ddc_pin;
};

struct gmbus_port {
	struct inteldrm_softc *dev_priv;
	int port;
};

enum intel_pch {
	PCH_NONE = 0,	/* No PCH present */
	PCH_IBX,	/* Ibexpeak PCH */
	PCH_CPT,	/* Cougarpoint PCH */
	PCH_LPT,	/* Lynxpoint PCH */
};

enum intel_sbi_destination {
	SBI_ICLK,
	SBI_MPHY,
};

#define QUIRK_PIPEA_FORCE	(1<<0)
#define QUIRK_LVDS_SSC_DISABLE	(1<<1)
#define QUIRK_INVERT_BRIGHTNESS	(1<<2)

struct intel_fbdev;

struct intel_gmbus {
	struct i2c_controller	 controller;
	struct gmbus_port	 gp;
};

struct i915_suspend_saved_registers {
	u8 saveLBB;
	u32 saveDSPACNTR;
	u32 saveDSPBCNTR;
	u32 saveDSPARB;
	u32 savePIPEACONF;
	u32 savePIPEBCONF;
	u32 savePIPEASRC;
	u32 savePIPEBSRC;
	u32 saveFPA0;
	u32 saveFPA1;
	u32 saveDPLL_A;
	u32 saveDPLL_A_MD;
	u32 saveHTOTAL_A;
	u32 saveHBLANK_A;
	u32 saveHSYNC_A;
	u32 saveVTOTAL_A;
	u32 saveVBLANK_A;
	u32 saveVSYNC_A;
	u32 saveBCLRPAT_A;
	u32 saveTRANSACONF;
	u32 saveTRANS_HTOTAL_A;
	u32 saveTRANS_HBLANK_A;
	u32 saveTRANS_HSYNC_A;
	u32 saveTRANS_VTOTAL_A;
	u32 saveTRANS_VBLANK_A;
	u32 saveTRANS_VSYNC_A;
	u32 savePIPEASTAT;
	u32 saveDSPASTRIDE;
	u32 saveDSPASIZE;
	u32 saveDSPAPOS;
	u32 saveDSPAADDR;
	u32 saveDSPASURF;
	u32 saveDSPATILEOFF;
	u32 savePFIT_PGM_RATIOS;
	u32 saveBLC_HIST_CTL;
	u32 saveBLC_PWM_CTL;
	u32 saveBLC_PWM_CTL2;
	u32 saveBLC_CPU_PWM_CTL;
	u32 saveBLC_CPU_PWM_CTL2;
	u32 saveFPB0;
	u32 saveFPB1;
	u32 saveDPLL_B;
	u32 saveDPLL_B_MD;
	u32 saveHTOTAL_B;
	u32 saveHBLANK_B;
	u32 saveHSYNC_B;
	u32 saveVTOTAL_B;
	u32 saveVBLANK_B;
	u32 saveVSYNC_B;
	u32 saveBCLRPAT_B;
	u32 saveTRANSBCONF;
	u32 saveTRANS_HTOTAL_B;
	u32 saveTRANS_HBLANK_B;
	u32 saveTRANS_HSYNC_B;
	u32 saveTRANS_VTOTAL_B;
	u32 saveTRANS_VBLANK_B;
	u32 saveTRANS_VSYNC_B;
	u32 savePIPEBSTAT;
	u32 saveDSPBSTRIDE;
	u32 saveDSPBSIZE;
	u32 saveDSPBPOS;
	u32 saveDSPBADDR;
	u32 saveDSPBSURF;
	u32 saveDSPBTILEOFF;
	u32 saveVGA0;
	u32 saveVGA1;
	u32 saveVGA_PD;
	u32 saveVGACNTRL;
	u32 saveADPA;
	u32 saveLVDS;
	u32 savePP_ON_DELAYS;
	u32 savePP_OFF_DELAYS;
	u32 saveDVOA;
	u32 saveDVOB;
	u32 saveDVOC;
	u32 savePP_ON;
	u32 savePP_OFF;
	u32 savePP_CONTROL;
	u32 savePP_DIVISOR;
	u32 savePFIT_CONTROL;
	u32 save_palette_a[256];
	u32 save_palette_b[256];
	u32 saveDPFC_CB_BASE;
	u32 saveFBC_CFB_BASE;
	u32 saveFBC_LL_BASE;
	u32 saveFBC_CONTROL;
	u32 saveFBC_CONTROL2;
	u32 saveIER;
	u32 saveIIR;
	u32 saveIMR;
	u32 saveDEIER;
	u32 saveDEIMR;
	u32 saveGTIER;
	u32 saveGTIMR;
	u32 saveFDI_RXA_IMR;
	u32 saveFDI_RXB_IMR;
	u32 saveCACHE_MODE_0;
	u32 saveMI_ARB_STATE;
	u32 saveSWF0[16];
	u32 saveSWF1[16];
	u32 saveSWF2[3];
	u8 saveMSR;
	u8 saveSR[8];
	u8 saveGR[25];
	u8 saveAR_INDEX;
	u8 saveAR[21];
	u8 saveDACMASK;
	u8 saveCR[37];
	uint64_t saveFENCE[I915_MAX_NUM_FENCES];
	u32 saveCURACNTR;
	u32 saveCURAPOS;
	u32 saveCURABASE;
	u32 saveCURBCNTR;
	u32 saveCURBPOS;
	u32 saveCURBBASE;
	u32 saveCURSIZE;
	u32 saveDP_B;
	u32 saveDP_C;
	u32 saveDP_D;
	u32 savePIPEA_GMCH_DATA_M;
	u32 savePIPEB_GMCH_DATA_M;
	u32 savePIPEA_GMCH_DATA_N;
	u32 savePIPEB_GMCH_DATA_N;
	u32 savePIPEA_DP_LINK_M;
	u32 savePIPEB_DP_LINK_M;
	u32 savePIPEA_DP_LINK_N;
	u32 savePIPEB_DP_LINK_N;
	u32 saveFDI_RXA_CTL;
	u32 saveFDI_TXA_CTL;
	u32 saveFDI_RXB_CTL;
	u32 saveFDI_TXB_CTL;
	u32 savePFA_CTL_1;
	u32 savePFB_CTL_1;
	u32 savePFA_WIN_SZ;
	u32 savePFB_WIN_SZ;
	u32 savePFA_WIN_POS;
	u32 savePFB_WIN_POS;
	u32 savePCH_DREF_CONTROL;
	u32 saveDISP_ARB_CTL;
	u32 savePIPEA_DATA_M1;
	u32 savePIPEA_DATA_N1;
	u32 savePIPEA_LINK_M1;
	u32 savePIPEA_LINK_N1;
	u32 savePIPEB_DATA_M1;
	u32 savePIPEB_DATA_N1;
	u32 savePIPEB_LINK_M1;
	u32 savePIPEB_LINK_N1;
	u32 saveMCHBAR_RENDER_STANDBY;
	u32 savePCH_PORT_HOTPLUG;
};

struct intel_gen6_power_mgmt {
	struct workq_task task;
	u32 pm_iir;
	/* lock - irqsave spinlock that protectects the work_struct and
	 * pm_iir. */
	struct mutex lock;

	/* The below variables an all the rps hw state are protected by
	 * dev->struct mutext. */
	u8 cur_delay;
	u8 min_delay;
	u8 max_delay;

#if 0
	struct delayed_work delayed_resume_work;
#endif

	/*
	 * Protects RPS/RC6 register access and PCU communication.
	 * Must be taken after struct_mutex if nested.
	 */
	struct rwlock hw_lock;
};

struct intel_ilk_power_mgmt {
	u8 cur_delay;
	u8 min_delay;
	u8 max_delay;
	u8 fmax;
	u8 fstart;

	u64 last_count1;
	unsigned long last_time1;
	unsigned long chipset_power;
	u64 last_count2;
	struct timespec last_time2;
	unsigned long gfx_power;
	u8 corr;

	int c_m;
	int r_t;

	struct drm_i915_gem_object *pwrctx;
	struct drm_i915_gem_object *renderctx;
};

struct intel_l3_parity {
	u32 *remap_info;
	struct workq_task error_task;
};

/*
 * lock ordering:
 * exec lock,
 * request lock
 * list lock.
 *
 * XXX fence lock ,object lock
 */
struct inteldrm_softc {
	struct device		 dev;
	struct device		*drmdev;
	bus_dma_tag_t		 agpdmat; /* tag from intagp for GEM */
	bus_dma_tag_t		 dmat;
	bus_space_tag_t		 bst;
	struct agp_map		*agph;
	bus_space_handle_t	 opregion_ioh;

	u_long			 flags;

	struct intel_gmbus	 gmbus[GMBUS_NUM_PORTS];

	pci_chipset_tag_t	 pc;
	pcitag_t		 tag;
	pci_intr_handle_t	 ih;
	void			*irqh;

	struct vga_pci_bar	*regs;

	int			 nscreens;
	void			(*switchcb)(void *, int, int);
	void			*switchcbarg;
	struct workq_task	 switchwqt;
	struct rasops_info	 ro;

	int			 noaccel;
	struct wsdisplay_emulops noaccel_ops;

	uint32_t		 gpio_mmio_base;

	struct drm_i915_gt_funcs gt;
	/** gt_fifo_count and the subsequent register write are synchronized
	 * with dev->struct_mutex. */
	unsigned gt_fifo_count;
	/** forcewake_count is protected by gt_lock */
	unsigned forcewake_count;
	/** gt_lock is also taken in irq contexts. */
	struct mutex gt_lock;

	drm_i915_sarea_t *sarea_priv;
	struct intel_ring_buffer rings[I915_NUM_RINGS];
	uint32_t next_seqno;

	struct drm_dmamem *status_page_dmah;

	union flush {
		struct {
			bus_space_tag_t		bst;
			bus_space_handle_t	bsh;
		} i9xx;
		struct {
			bus_dma_segment_t	seg;
			caddr_t			kva;
		} i8xx;
	}			 ifp;
	struct workq		*workq;
	struct vm_page		*pgs;
	size_t			 max_gem_obj_size; /* XXX */

	/* Protects user_irq_refcount and irq_mask reg */
	struct mutex		 irq_lock;
	/* Refcount for user irq, only enabled when needed */
	int			 user_irq_refcount;
	u_int32_t		 irq_mask;

	/* DPIO indirect register protection */
	struct mutex		 dpio_lock;
	/* Cached value of IMR to avoid reads in updating the bitfield */
	u_int32_t		 pipestat[2];
	/* these two  ironlake only, we should union this with pipestat XXX */
	u_int32_t		 gt_irq_mask;
	u_int32_t		 pch_irq_mask;

	u_int32_t		 hotplug_supported_mask;
	struct workq_task	 hotplug_task;

	int			 num_pipe;
	int			 num_pch_pll;

	struct intel_opregion	 opregion;

	int crt_ddc_pin;

	/* overlay */
        struct intel_overlay *overlay;
	bool sprite_scaling_enabled;

	/* LVDS info */
	int backlight_level;  /* restore backlight to this value */
	bool backlight_enabled;
	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */

	/* Feature bits from the VBIOS */
	unsigned int int_tv_support:1;
	unsigned int lvds_dither:1;
	unsigned int lvds_vbt:1;
	unsigned int int_crt_support:1;
	unsigned int lvds_use_ssc:1;
	unsigned int display_clock_mode:1;
	int lvds_ssc_freq;
	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
	unsigned int lvds_val; /* used for checking LVDS channel mode */
	struct {
		int rate;
		int lanes;
		int preemphasis;
		int vswing;

		bool initialized;
		bool support;
		int bpp;
		struct edp_power_seq pps;
	} edp;
	bool no_aux_handshake;

	struct intel_pch_pll	 pch_plls[I915_NUM_PLLS];
	struct intel_ddi_plls	 ddi_plls;

	/* Reclocking support */
	bool			 render_reclock_avail;
	bool			 lvds_downclock_avail;
	int			 lvds_downclock;
	bool			 busy;
	int			 child_dev_num;
	struct child_device_config *child_dev;

	struct drm_i915_fence_reg fence_regs[16]; /* 965 */
	int			 fence_reg_start; /* 4 by default */
	int			 num_fence_regs; /* 8 pre-965, 16 post */

#define	INTELDRM_QUIET		0x01 /* suspend close, get off the hardware */
#define	INTELDRM_WEDGED		0x02 /* chipset hung pending reset */
#define	INTELDRM_SUSPENDED	0x04 /* in vt switch, no commands */
	int			 sc_flags; /* quiet, suspended, hung */
	/* number of ioctls + faults in flight */
	int			 entries;

	struct workq_task error_task;

	enum intel_pch pch_type;
	unsigned short pch_id;

	struct drm_i915_display_funcs display;

	struct timeout idle_timeout;

	unsigned long quirks;

	/* Register state */
	bool modeset_on_lid;

	struct {
		/** List of all objects in gtt_space. Used to restore gtt
		 * mappings on resume */
		struct list_head bound_list;

		/**
		 * List of objects currently involved in rendering from the
		 * ringbuffer.
		 *
		 * Includes buffers having the contents of their GPU caches
		 * flushed, not necessarily primitives. last_rendering_seqno
		 * represents when the rendering involved will be completed.
		 *
		 * A reference is held on the buffer while on this list.
		 */
		struct list_head active_list;

		/**
		 * LRU list of objects which are not in the ringbuffer and
		 * are ready to unbind, but are still in the GTT.
		 *
		 * last_rendering_seqno is 0 while an object is in this list
		 *
		 * A reference is not held on the buffer while on this list,
		 * as merely being GTT-bound shouldn't prevent its being
		 * freed, and we'll pull it off the list in the free path.
		 */
		struct list_head inactive_list;

		/* Fence LRU */
		struct list_head fence_list;

		/**
		 * We leave the user IRQ off as much as possible,
		 * but this means that requests will finish and never
		 * be retired once the system goes idle. Set a timer to
		 * fire periodically while the ring is running. When it
		 * fires, go retire requests in a workq.
		 */
		struct timeout retire_timer;

		/**
		 * Are we in a non-interruptible section of code like
		 * modesetting?
		 */
		bool interruptible;

		/**
		 * Flag if the X Server, and thus DRM, is not currently in
		 * control of the device.
		 *
		 * This is set between LeaveVT and EnterVT.  It needs to be
		 * replaced with a semaphore.  It also needs to be
		 * transitioned away from for kernel modesetting.
		 */
		int suspended;

		/**
		 * Flag if the hardware appears to be wedged.
		 *
		 * This is set when attempts to idle the device timeout.
		 * It prevents command submission from occuring and makes
		 * every pending request fail
		 */
		int wedged;

		/** Bit 6 swizzling required for X tiling */
		uint32_t bit_6_swizzle_x;
		/** Bit 6 swizzling required for Y tiling */
		uint32_t bit_6_swizzle_y;

		/* storage for physical objects */
		struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
	} mm;

	/* for hangcheck */
#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
	struct timeout hangcheck_timer;
	int hangcheck_count;
	uint32_t last_acthd[I915_NUM_RINGS];
	uint32_t prev_instdone[I915_NUM_INSTDONE_REG];

	const struct intel_device_info *info;

	int relative_constants_mode;

	struct sdvo_device_mapping sdvo_mappings[2];
	/* indicate whether the LVDS_BORDER should be enabled or not */
	unsigned int lvds_border_bits;
	/* Panel fitter placement and size for Ironlake+ */
	u32 pch_pf_pos, pch_pf_size;

	struct drm_crtc *plane_to_crtc_mapping[3];
	struct drm_crtc *pipe_to_crtc_mapping[3];
	int pending_flip_queue;

	bool flip_pending_is_done;

	struct drm_connector *int_lvds_connector;
	struct drm_connector *int_edp_connector;

	u8 cur_delay;
	u8 min_delay;
	u8 max_delay;
	u8 fmax;
	u8 fstart;

	u64 last_count1;
	unsigned long last_time1;
	unsigned long chipset_power;
	u64 last_count2;
//	struct timespec last_time2;
	unsigned long gfx_power;
	int c_m;
	int r_t;
	u8 corr;

	struct intel_l3_parity l3_parity;

	/* gen6+ rps state */
	struct intel_gen6_power_mgmt rps;

	/* ilk-only ips/rps state. Everything in here is protected by the global
	 * mchdev_lock in intel_pm.c */
	struct intel_ilk_power_mgmt ips;

	enum no_fbc_reason no_fbc_reason;

	unsigned int stop_rings;

	unsigned long cfb_size;
	unsigned int cfb_fb;
	int cfb_plane;
	int cfb_y;
	struct intel_fbc_work *fbc_work;

	unsigned int fsb_freq, mem_freq, is_ddr3;

	int error_completion;
	struct mutex error_completion_lock;

	time_t last_gpu_reset;

	struct intel_fbdev *fbdev;

	struct drm_property *broadcast_rgb_property;
	struct drm_property *force_audio_property;

	u32 fdi_rx_config;

	struct i915_suspend_saved_registers regfile;
};
typedef struct inteldrm_softc drm_i915_private_t;

/* Iterate over initialised rings */
#define for_each_ring(ring__, dev_priv__, i__) \
	for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
		if (((ring__) = &(dev_priv__)->rings[(i__)]), intel_ring_initialized((ring__)))

enum hdmi_force_audio {
	HDMI_AUDIO_OFF_DVI = -2,	/* no aux data for HDMI-DVI converter */
	HDMI_AUDIO_OFF,			/* force turn off HDMI audio */
	HDMI_AUDIO_AUTO,		/* trust EDID */
	HDMI_AUDIO_ON,			/* force turn on HDMI audio */
};

enum i915_cache_level {
	I915_CACHE_NONE,
	I915_CACHE_LLC,
	I915_CACHE_LLC_MLC, /* gen6+ */
};

struct inteldrm_file {
	struct drm_file	file_priv;
	struct {
	} mm;
};

/* chip type flags */
#define CHIP_I830	0x00001
#define CHIP_I845G	0x00002
#define CHIP_I85X	0x00004
#define CHIP_I865G	0x00008
#define CHIP_I9XX	0x00010
#define CHIP_I915G	0x00020
#define CHIP_I915GM	0x00040
#define CHIP_I945G	0x00080
#define CHIP_I945GM	0x00100
#define CHIP_I965	0x00200
#define CHIP_I965GM	0x00400
#define CHIP_G33	0x00800
#define CHIP_GM45	0x01000
#define CHIP_G4X	0x02000
#define CHIP_M		0x04000
#define CHIP_HWS	0x08000
#define CHIP_GEN2	0x10000
#define CHIP_GEN3	0x20000
#define CHIP_GEN4	0x40000
#define CHIP_GEN6	0x80000
#define	CHIP_PINEVIEW	0x100000
#define	CHIP_IRONLAKE	0x200000
#define CHIP_IRONLAKE_D	0x400000
#define CHIP_IRONLAKE_M	0x800000
#define CHIP_SANDYBRIDGE	0x1000000
#define CHIP_IVYBRIDGE	0x2000000
#define CHIP_GEN7	0x4000000

/* flags we use in drm_obj's do_flags */
#define I915_IN_EXEC		0x0020	/* being processed in execbuffer */
#define I915_USER_PINNED	0x0040	/* BO has been pinned from userland */
#define I915_EXEC_NEEDS_FENCE	0x0800	/* being processed but will need fence*/

/** driver private structure attached to each drm_gem_object */
struct drm_i915_gem_object {
	struct drm_obj				 base;

	struct list_head gtt_list;

	/** This object's place on the active/flushing/inactive lists */
	struct list_head			 ring_list;
	struct list_head			 mm_list;
	/* GTT binding. */
	bus_dmamap_t				 dmamap;
	bus_dma_segment_t			*dma_segs;
	/* Current offset of the object in GTT space. */
	bus_addr_t				 gtt_offset;
	struct intel_ring_buffer		*ring;
	u_int32_t				*bit_17;
	/* extra flags to bus_dma */
	int					 dma_flags;
	/* Fence register for this object. needed for tiling. */
	int					 fence_reg;
	/** refcount for times pinned this object in GTT space */
	int					 pin_count;
	/* number of times pinned by pin ioctl. */
	u_int					 user_pin_count;

	/** Breadcrumb of last rendering to the buffer. */
	u_int32_t				 last_read_seqno;
	u_int32_t				 last_write_seqno;
	/** Breadcrumb of last fenced GPU access to the buffer. */
	u_int32_t				 last_fenced_seqno;
	/** Current tiling mode for the object. */
	u_int32_t				 tiling_mode;
	u_int32_t				 stride;

	/**
	 * This is set if the object is on the active lists (has pending
	 * rendering and so a non-zero seqno), and is not set if it i s on
	 * inactive (ready to be unbound) list.
	 */
	unsigned int active:1;

	/**
	 * This is set if the object has been written to since last bound
	 * to the GTT
	 */
	unsigned int dirty:1;

	/**
	 * Advice: are the backing pages purgeable?
	 */
	unsigned int madv:2;

	/**
	 * Whether the tiling parameters for the currently associated fence
	 * register have changed. Note that for the purposes of tracking
	 * tiling changes we also treat the unfenced register, the register
	 * slot that the object occupies whilst it executes a fenced
	 * command (such as BLT on gen2/3), as a "fence".
	 */
	unsigned int fence_dirty:1;

	/**
	 * Is the object at the current location in the gtt mappable and
	 * fenceable? Used to avoid costly recalculations.
	 */
	unsigned int map_and_fenceable:1;

	/**
	 * Whether the current gtt mapping needs to be mappable (and isn't just
	 * mappable by accident). Track pin and fault separate for a more
	 * accurate mappable working set.
	 */
	unsigned int fault_mappable:1;
	unsigned int pin_mappable:1;

	/*
	 * Is the GPU currently using a fence to access this buffer,
	 */
	unsigned int pending_fenced_gpu_access:1;
	unsigned int fenced_gpu_access:1;

	unsigned int cache_level:2;

	/** for phy allocated objects */
	struct drm_i915_gem_phys_object *phys_obj;

	/**
	 * Number of crtcs where this object is currently the fb, but   
	 * will be page flipped away on the next vblank.  When it
	 * reaches 0, dev_priv->pending_flip_queue will be woken up.
	 */
	int					 pending_flip;
};
#define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base)

#define to_intel_bo(x) container_of(x,struct drm_i915_gem_object, base)

struct drm_i915_file_private {
	struct {
		struct mutex lock;
		struct list_head request_list;
	} mm;
};

/**
 * Request queue structure.
 *
 * The request queue allows us to note sequence numbers that have been emitted
 * and may be associated with active buffers to be retired.
 *
 * By keeping this list, we can avoid having to do questionable
 * sequence-number comparisons on buffer last_rendering_seqnos, and associate
 * an emission time with seqnos for tracking how far ahead of the GPU we are.
 */
struct drm_i915_gem_request {
	struct list_head			list;
	/** On Which ring this request was generated */
	struct intel_ring_buffer	*ring;
	/** GEM sequence number associated with this request. */
	uint32_t			seqno;
	/** Postion in the ringbuffer of the end of the request */
	uint32_t			tail;
	/** Time at which this request was emitted, in ticks. */
	unsigned long			emitted_ticks;
	struct drm_i915_file_private	*file_priv;
	/** file_priv list entry for this request */
	struct list_head		client_list;
};

u_int32_t	inteldrm_read_hws(struct inteldrm_softc *, int);
int		ring_wait_for_space(struct intel_ring_buffer *, int n);
int		intel_ring_begin(struct intel_ring_buffer *, int);
void		intel_ring_emit(struct intel_ring_buffer *, u_int32_t);
void		intel_ring_advance(struct intel_ring_buffer *);
void		inteldrm_update_ring(struct intel_ring_buffer *);
int		inteldrm_pipe_enabled(struct inteldrm_softc *, int);
int		i915_init_phys_hws(struct inteldrm_softc *, bus_dma_tag_t);

unsigned long	i915_chipset_val(struct inteldrm_softc *dev_priv);
unsigned long	i915_mch_val(struct inteldrm_softc *dev_priv);
unsigned long	i915_gfx_val(struct inteldrm_softc *dev_priv);
void		i915_update_gfx_val(struct inteldrm_softc *);

int		intel_init_ring_buffer(struct drm_device *,
		    struct intel_ring_buffer *);
int		init_ring_common(struct intel_ring_buffer *);

int		intel_init_render_ring_buffer(struct drm_device *);
void		intel_cleanup_ring_buffer(struct intel_ring_buffer *);

/* i915_irq.c */

extern int i915_driver_irq_install(struct drm_device * dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev);
extern int i915_enable_vblank(struct drm_device *dev, int crtc);
extern void i915_disable_vblank(struct drm_device *dev, int crtc);
extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern void i915_user_irq_get(struct inteldrm_softc *);
extern void i915_user_irq_put(struct inteldrm_softc *);
void	i915_enable_pipestat(struct inteldrm_softc *, int, u_int32_t);
void	i915_disable_pipestat(struct inteldrm_softc *, int, u_int32_t);
void	intel_irq_init(struct drm_device *dev);
void	i915_hangcheck_elapsed(void *);

extern void intel_gt_init(struct drm_device *dev);
extern void intel_gt_reset(struct drm_device *dev);

/* gem */
/* Ioctls */
int	i915_gem_init_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_create_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_pread_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_pwrite_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_set_domain_ioctl(struct drm_device *, void *,
	    struct drm_file *);
int	i915_gem_execbuffer2(struct drm_device *, void *, struct drm_file *);
int	i915_gem_pin_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_unpin_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_busy_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_entervt_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_leavevt_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_get_aperture_ioctl(struct drm_device *, void *,
	    struct drm_file *);
int	i915_gem_set_tiling(struct drm_device *, void *, struct drm_file *);
int	i915_gem_get_tiling(struct drm_device *, void *, struct drm_file *);
int	i915_gem_gtt_map_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_mmap_gtt_ioctl(struct drm_device *, void *, struct drm_file *);
int	i915_gem_madvise_ioctl(struct drm_device *, void *, struct drm_file *);

/* GEM memory manager functions */
int	i915_gem_init_object(struct drm_obj *);
void	i915_gem_free_object(struct drm_obj *);
int	i915_gem_object_pin(struct drm_i915_gem_object *, uint32_t, bool);
void	i915_gem_object_unpin(struct drm_i915_gem_object *);
void	i915_gem_retire_request(struct inteldrm_softc *,
	    struct drm_i915_gem_request *);
void	i915_gem_retire_requests_ring(struct intel_ring_buffer *);
int	i915_gem_check_wedge(struct inteldrm_softc *,
			     bool interruptible);

void	i915_gem_retire_work_handler(void *, void*);
int	i915_gem_idle(struct inteldrm_softc *);
void	i915_gem_object_move_to_active(struct drm_i915_gem_object *,
	    struct intel_ring_buffer *);
void	i915_gem_object_move_to_inactive(struct drm_i915_gem_object *);
void	i915_gem_object_move_to_inactive_locked(struct drm_i915_gem_object *);
int	i915_add_request(struct intel_ring_buffer *, struct drm_file *, u32 *);
int	init_pipe_control(struct intel_ring_buffer *);
void	cleanup_status_page(struct intel_ring_buffer *);
void	i915_gem_init_swizzling(struct drm_device *);
void	i915_gem_cleanup_ringbuffer(struct drm_device *);
int	i915_gem_ring_throttle(struct drm_device *, struct drm_file *);
int	i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object2 *,
	    u_int32_t, struct drm_i915_gem_relocation_entry **);
int	i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object2 *,
	    u_int32_t, struct drm_i915_gem_relocation_entry *);
void	i915_dispatch_gem_execbuffer(struct intel_ring_buffer *,
	    struct drm_i915_gem_execbuffer2 *, uint64_t);
int	i915_gem_object_pin_and_relocate(struct drm_obj *,
	    struct drm_file *, struct drm_i915_gem_exec_object2 *,
	    struct drm_i915_gem_relocation_entry *);

struct drm_obj	*i915_gem_find_inactive_object(struct inteldrm_softc *,
		     size_t);

extern int i915_gem_get_seqno(struct drm_device *, u32 *);

int	i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *,
	    bool);
int	i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *,
	    u32, struct intel_ring_buffer *);
int	i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *,
	    bool);
int	i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *);
int	i915_gem_object_wait_rendering(struct drm_i915_gem_object *, bool);

int	i915_gem_init(struct drm_device *);
int	i915_gem_mmap_gtt(struct drm_file *, struct drm_device *,
	    uint32_t, uint64_t *);
int	i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
	    enum i915_cache_level cache_level);

void	sandybridge_write_fence_reg(struct drm_device *, int,
	    struct drm_i915_gem_object *);
void	i965_write_fence_reg(struct drm_device *, int,
	    struct drm_i915_gem_object *);
void	i915_write_fence_reg(struct drm_device *, int,
	    struct drm_i915_gem_object *);
void	i830_write_fence_reg(struct drm_device *, int,
	    struct drm_i915_gem_object *);

int	i915_gem_object_finish_gpu(struct drm_i915_gem_object *);
int	i915_gem_init_hw(struct drm_device *);

/* Debug functions, mostly called from ddb */
void	i915_gem_seqno_info(int);
void	i915_interrupt_info(int);
void	i915_gem_fence_regs_info(int);
void	i915_hws_info(int);
void	i915_batchbuffer_info(int);
void	i915_ringbuffer_data(int);
void	i915_ringbuffer_info(int);
#ifdef WATCH_INACTIVE
void inteldrm_verify_inactive(struct inteldrm_softc *, char *, int);
#else
#define inteldrm_verify_inactive(dev,file,line)
#endif

void i915_gem_retire_requests(struct inteldrm_softc *);
struct drm_obj  *i915_gem_find_inactive_object(struct inteldrm_softc *,
	size_t);
int i915_gem_object_unbind(struct drm_i915_gem_object *);
int i915_wait_seqno(struct intel_ring_buffer *, uint32_t);
#define I915_GEM_GPU_DOMAINS	(~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))

void i915_gem_detach_phys_object(struct drm_device *,
    struct drm_i915_gem_object *);
int i915_gem_attach_phys_object(struct drm_device *dev,
    struct drm_i915_gem_object *, int, int);

int i915_gem_dumb_create(struct drm_file *, struct drm_device *,
    struct drm_mode_create_dumb *);
int i915_gem_mmap_gtt(struct drm_file *, struct drm_device *,
    uint32_t, uint64_t *);
int i915_gem_dumb_destroy(struct drm_file *, struct drm_device *,
    uint32_t);

/* i915_dma.c */
void	i915_driver_lastclose(struct drm_device *);
int	intel_setup_mchbar(struct inteldrm_softc *,
	    struct pci_attach_args *);
void	intel_teardown_mchbar(struct inteldrm_softc *,
	    struct pci_attach_args *, int);
int	i915_getparam(struct inteldrm_softc *dev_priv, void *data);
int	i915_setparam(struct inteldrm_softc *dev_priv, void *data);
void	i915_kernel_lost_context(struct drm_device *);
int	i915_driver_open(struct drm_device *, struct drm_file *);
void	i915_driver_close(struct drm_device *, struct drm_file *);

/* i915_drv.c */
void	inteldrm_wipe_mappings(struct drm_obj *);
void	inteldrm_set_max_obj_size(struct inteldrm_softc *);
void	inteldrm_purge_obj(struct drm_obj *);
void	i915_gem_chipset_flush(struct drm_device *);
int	intel_gpu_reset(struct drm_device *);
int	i915_reset(struct drm_device *);
void	inteldrm_timeout(void *);
bool	i915_semaphore_is_enabled(struct drm_device *);

/* i915_gem_evict.c */
int i915_gem_evict_everything(struct inteldrm_softc *);
int i915_gem_evict_something(struct inteldrm_softc *, size_t);
int i915_gem_evict_inactive(struct inteldrm_softc *);

/* i915_gem_tiling.c */
void	i915_gem_detect_bit_6_swizzle(struct inteldrm_softc *, 
	    struct pci_attach_args *);
void	i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *);
void	i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *);
int	i915_gem_swizzle_page(struct vm_page *page);
int	i915_tiling_ok(struct drm_device *, int, int, int);
bool	i915_gem_object_fence_ok(struct drm_i915_gem_object *, int);

/* i915_gem_debug.c */
#define i915_verify_lists(dev) 0

/* i915_suspend.c */
extern void i915_save_display(struct drm_device *);
extern void i915_restore_display(struct drm_device *);
extern int i915_save_state(struct drm_device *);
extern int i915_restore_state(struct drm_device *);

/* intel_i2c.c */
extern int intel_setup_gmbus(struct inteldrm_softc *);
struct i2c_controller *intel_gmbus_get_adapter(drm_i915_private_t *, unsigned);
static inline bool intel_gmbus_is_port_valid(unsigned port)
{
	return (port >= GMBUS_PORT_SSC && port <= GMBUS_PORT_DPD);
}

/* i915_gem.c */
int i915_gem_create(struct drm_file *, struct drm_device *, uint64_t,
    uint32_t *);
void init_ring_lists(struct intel_ring_buffer *);
int i915_gem_fault(struct drm_obj *, struct uvm_faultinfo *, off_t,
    vaddr_t, vm_page_t *, int, int, vm_prot_t, int );
struct drm_i915_gem_object *
    i915_gem_alloc_object(struct drm_device *, size_t);
int i915_gpu_idle(struct drm_device *);
void i915_gem_object_move_to_flushing(struct drm_i915_gem_object *);
void i915_gem_write_fence(struct drm_device *, int,
    struct drm_i915_gem_object *);
void i915_gem_reset_fences(struct drm_device *);
int i915_gem_object_get_fence(struct drm_i915_gem_object *);
int i915_gem_object_put_fence(struct drm_i915_gem_object *);
void i915_gem_reset(struct drm_device *);
void i915_gem_clflush_object(struct drm_i915_gem_object *);
void i915_gem_release(struct drm_device *, struct drm_file *);

uint32_t
i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev,
				    uint32_t size,
				    int tiling_mode);

int i915_gem_object_sync(struct drm_i915_gem_object *,
    struct intel_ring_buffer *);

int i915_mutex_lock_interruptible(struct drm_device *dev);

/* intel_opregion.c */
int intel_opregion_setup(struct drm_device *dev);
extern int intel_opregion_init(struct drm_device *dev);
extern void intel_opregion_fini(struct drm_device *dev);
extern void opregion_asle_intr(struct drm_device *dev);
extern void opregion_enable_asle(struct drm_device *dev);

/* i915_gem_gtt.c */
void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev);
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj,
				enum i915_cache_level);

/* modesetting */
extern void intel_modeset_init_hw(struct drm_device *dev);
extern void intel_modeset_init(struct drm_device *dev);
extern void intel_modeset_gem_init(struct drm_device *dev);
extern void intel_modeset_cleanup(struct drm_device *dev);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
extern void intel_modeset_setup_hw_state(struct drm_device *dev,
					 bool force_restore);
extern bool intel_fbc_enabled(struct drm_device *dev);
extern void intel_disable_fbc(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
extern void intel_init_pch_refclk(struct drm_device *dev);
extern void ironlake_init_pch_refclk(struct drm_device *dev);
extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void intel_detect_pch(struct inteldrm_softc *dev_priv);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
int i915_load_modeset_init(struct drm_device *dev);
extern int intel_enable_rc6(const struct drm_device *dev);

extern void __gen6_gt_force_wake_get(struct inteldrm_softc *dev_priv);
extern void __gen6_gt_force_wake_mt_get(struct inteldrm_softc *dev_priv);
extern void __gen6_gt_force_wake_put(struct inteldrm_softc *dev_priv);
extern void __gen6_gt_force_wake_mt_put(struct inteldrm_softc *dev_priv);

extern struct intel_overlay_error_state *intel_overlay_capture_error_state(
    struct drm_device *dev);
#ifdef notyet
extern void intel_overlay_print_error_state(struct sbuf *m,
    struct intel_overlay_error_state *error);
#endif
extern struct intel_display_error_state *intel_display_capture_error_state(
    struct drm_device *dev);
#ifdef notyet
extern void intel_display_print_error_state(struct sbuf *m,
    struct drm_device *dev, struct intel_display_error_state *error);
#endif

/* On SNB platform, before reading ring registers forcewake bit
 * must be set to prevent GT core from power down and stale values being
 * returned.
 */
void gen6_gt_force_wake_get(struct inteldrm_softc *dev_priv);
void gen6_gt_force_wake_put(struct inteldrm_softc *dev_priv);
int __gen6_gt_wait_for_fifo(struct inteldrm_softc *dev_priv);

int sandybridge_pcode_read(struct inteldrm_softc *dev_priv, u8 mbox, u32 *val);
int sandybridge_pcode_write(struct inteldrm_softc *dev_priv, u8 mbox, u32 val);

/* XXX need bus_space_write_8, this evaluated arguments twice */
static __inline void
write64(struct inteldrm_softc *dev_priv, bus_size_t off, u_int64_t reg)
{
	bus_space_write_4(dev_priv->regs->bst, dev_priv->regs->bsh,
	    off, (u_int32_t)reg);
	bus_space_write_4(dev_priv->regs->bst, dev_priv->regs->bsh,
	    off + 4, upper_32_bits(reg));
}

static __inline u_int64_t
read64(struct inteldrm_softc *dev_priv, bus_size_t off)
{
	u_int32_t low, high;

	low = bus_space_read_4(dev_priv->regs->bst,
	    dev_priv->regs->bsh, off);
	high = bus_space_read_4(dev_priv->regs->bst,
	    dev_priv->regs->bsh, off + 4);

	return ((u_int64_t)low | ((u_int64_t)high << 32));
}

#define I915_READ64(off)	read64(dev_priv, off)

#define I915_WRITE64(off, reg)	write64(dev_priv, off, reg)

#define I915_READ(reg)		bus_space_read_4(dev_priv->regs->bst,	\
				    dev_priv->regs->bsh, (reg))
#define I915_READ_NOTRACE(reg)	I915_READ(reg)
#define I915_WRITE(reg,val)	bus_space_write_4(dev_priv->regs->bst,	\
				    dev_priv->regs->bsh, (reg), (val))
#define I915_WRITE_NOTRACE(reg,val)	I915_WRITE(reg, val)
#define I915_READ16(reg)	bus_space_read_2(dev_priv->regs->bst,	\
				    dev_priv->regs->bsh, (reg))
#define I915_WRITE16(reg,val)	bus_space_write_2(dev_priv->regs->bst,	\
				    dev_priv->regs->bsh, (reg), (val))
#define I915_READ8(reg)		bus_space_read_1(dev_priv->regs->bst,	\
				    dev_priv->regs->bsh, (reg))
#define I915_WRITE8(reg,val)	bus_space_write_1(dev_priv->regs->bst,	\
				    dev_priv->regs->bsh, (reg), (val))

#define POSTING_READ(reg)	(void)I915_READ(reg)
#define POSTING_READ16(reg)	(void)I915_READ16(reg)

#define INTELDRM_VERBOSE 0
#if INTELDRM_VERBOSE > 0
#define	INTELDRM_VPRINTF(fmt, args...) DRM_INFO(fmt, ##args)
#else
#define	INTELDRM_VPRINTF(fmt, args...)
#endif

#define LP_RING(d) (&((struct inteldrm_softc *)(d))->rings[RCS])

#define BEGIN_LP_RING(n) \
	intel_ring_begin(LP_RING(dev_priv), (n))

#define OUT_RING(x) \
	intel_ring_emit(LP_RING(dev_priv), (x))

#define ADVANCE_LP_RING() \
	intel_ring_advance(LP_RING(dev_priv))

/* MCH IFP BARs */
#define	I915_IFPADDR	0x60
#define I965_IFPADDR	0x70

/**
 * Reads a dword out of the status page, which is written to from the command
 * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
 * MI_STORE_DATA_IMM.
 *
 * The following dwords have a reserved meaning:
 * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
 * 0x04: ring 0 head pointer
 * 0x05: ring 1 head pointer (915-class)
 * 0x06: ring 2 head pointer (915-class)
 * 0x10-0x1b: Context status DWords (GM45)
 * 0x1f: Last written status offset. (GM45)
 *
 * The area from dword 0x20 to 0x3ff is available for driver usage.
 */
#define READ_HWSP(dev_priv, reg)  inteldrm_read_hws(dev_priv, reg)
#define I915_GEM_HWS_INDEX		0x20

#define INTEL_INFO(dev) (((struct inteldrm_softc *) (dev)->dev_private)->info)

/* Chipset type macros */

#define IS_I830(dev)		((dev)->pci_device == 0x3577)
#define IS_845G(dev)		((dev)->pci_device == 0x2562)
#define IS_I85X(dev)		(INTEL_INFO(dev)->is_i85x)
#define IS_I865G(dev)		((dev)->pci_device == 0x2572)
#define IS_I915G(dev)		(INTEL_INFO(dev)->is_i915g)
#define IS_I915GM(dev)		((dev)->pci_device == 0x2592)
#define IS_I945G(dev)		((dev)->pci_device == 0x2772)
#define IS_I945GM(dev)		(INTEL_INFO(dev)->is_i945gm)
#define IS_BROADWATER(dev)	(INTEL_INFO(dev)->is_broadwater)
#define IS_CRESTLINE(dev)	(INTEL_INFO(dev)->is_crestline)
#define IS_GM45(dev)		((dev)->pci_device == 0x2A42)
#define IS_G4X(dev)		(INTEL_INFO(dev)->is_g4x)
#define IS_PINEVIEW_G(dev)	((dev)->pci_device == 0xa001)
#define IS_PINEVIEW_M(dev)	((dev)->pci_device == 0xa011)
#define IS_PINEVIEW(dev)	(INTEL_INFO(dev)->is_pineview)
#define IS_G33(dev)		(INTEL_INFO(dev)->is_g33)
#define IS_IRONLAKE_D(dev)	((dev)->pci_device == 0x0042)
#define IS_IRONLAKE_M(dev)	((dev)->pci_device == 0x0046)
#define IS_IVYBRIDGE(dev)	(INTEL_INFO(dev)->is_ivybridge)
#define IS_IVB_GT1(dev)		((dev)->pci_device == 0x0156 || \
				 (dev)->pci_device == 0x0152 || \
				 (dev)->pci_device == 0x015a)
#define IS_SNB_GT1(dev)		((dev)->pci_device == 0x0102 || \
				 (dev)->pci_device == 0x0106 || \
				 (dev)->pci_device == 0x010A)
#define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)

#define IS_I9XX(dev)		(INTEL_INFO(dev)->gen >= 3)
#define IS_IRONLAKE(dev)	(INTEL_INFO(dev)->gen == 5)

#define IS_SANDYBRIDGE(dev)	(INTEL_INFO(dev)->gen == 6)
#define IS_SANDYBRIDGE_D(dev)	(IS_SANDYBRIDGE(dev) && \
 (INTEL_INFO(dev)->is_mobile == 0))
#define IS_SANDYBRIDGE_M(dev)	(IS_SANDYBRIDGE(dev) && \
 (INTEL_INFO(dev)->is_mobile == 1))
#define IS_VALLEYVIEW(dev)	(INTEL_INFO(dev)->is_valleyview)
#define IS_HASWELL(dev)	(INTEL_INFO(dev)->is_haswell)
#define IS_ULT(dev)	(IS_HASWELL(dev) && \
			 ((dev)->pci_device & 0xFF00) == 0x0A00)

/*
 * The genX designation typically refers to the render engine, so render
 * capability related checks should use IS_GEN, while display and other checks
 * have their own (e.g. HAS_PCH_SPLIT for ILK+ display, IS_foo for particular
 * chips, etc.).
 */
#define IS_GEN2(dev)		(INTEL_INFO(dev)->gen == 2)
#define IS_GEN3(dev)		(INTEL_INFO(dev)->gen == 3)
#define IS_GEN4(dev)		(INTEL_INFO(dev)->gen == 4)
#define IS_GEN5(dev)		(INTEL_INFO(dev)->gen == 5)
#define IS_GEN6(dev)		(INTEL_INFO(dev)->gen == 6)
#define IS_GEN7(dev)		(INTEL_INFO(dev)->gen == 7)

#define HAS_BSD(dev)		(INTEL_INFO(dev)->has_bsd_ring)
#define HAS_BLT(dev)		(INTEL_INFO(dev)->has_blt_ring)
#define HAS_LLC(dev)		(INTEL_INFO(dev)->has_llc)
#define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)

#define HAS_HW_CONTEXTS(dev)	(INTEL_INFO(dev)->gen >= 6)
#define HAS_ALIASING_PPGTT(dev)	(INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev))

#define HAS_OVERLAY(dev)	(INTEL_INFO(dev)->has_overlay)
#define OVERLAY_NEEDS_PHYSICAL(dev) \
    (INTEL_INFO(dev)->overlay_needs_physical)

/* Early gen2 have a totally busted CS tlb and require pinned batches. */
#define HAS_BROKEN_CS_TLB(dev)	(IS_I830(dev) || IS_845G(dev))

/*
 * With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
 * rows, which changes the alignment requirements and fence programming.
 */
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) &&	\
	!(IS_I915G(dev) || IS_I915GM(dev)))

#define HAS_RESET(dev)	(INTEL_INFO(dev)->gen >= 4 && \
    (!IS_GEN6(dev)) && (!IS_GEN7(dev)))

#define SUPPORTS_DIGITAL_OUTPUTS(dev)	(!IS_GEN2(dev) && !IS_PINEVIEW(dev))
#define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_GEN5(dev))
#define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_GEN5(dev))
#define SUPPORTS_EDP(dev)		(IS_IRONLAKE_M(dev))
#define SUPPORTS_TV(dev)		(INTEL_INFO(dev)->supports_tv)
#define I915_HAS_HOTPLUG(dev)		(INTEL_INFO(dev)->has_hotplug)

#define HAS_FW_BLC(dev)		(INTEL_INFO(dev)->gen > 2)
#define HAS_PIPE_CXSR(dev)	(INTEL_INFO(dev)->has_pipe_cxsr)
#define I915_HAS_FBC(dev)	(INTEL_INFO(dev)->has_fbc)

#define HAS_PIPE_CONTROL(dev)	(INTEL_INFO(dev)->gen >= 5)

#define INTEL_PCH_DEVICE_ID_MASK		0xff00
#define INTEL_PCH_IBX_DEVICE_ID_TYPE		0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE		0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE		0x1e00
#define INTEL_PCH_LPT_DEVICE_ID_TYPE		0x8c00
#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE		0x9c00

#define INTEL_PCH_TYPE(dev)	(((struct inteldrm_softc *) (dev)->dev_private)->pch_type)
#define HAS_PCH_LPT(dev)	(INTEL_PCH_TYPE(dev) == PCH_LPT)
#define HAS_PCH_CPT(dev)	(INTEL_PCH_TYPE(dev) == PCH_CPT)
#define HAS_PCH_IBX(dev)	(INTEL_PCH_TYPE(dev) == PCH_IBX)
#define HAS_PCH_SPLIT(dev)	(INTEL_PCH_TYPE(dev) != PCH_NONE)

#define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)

#define HAS_L3_GPU_CACHE(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))

#define PRIMARY_RINGBUFFER_SIZE         (128*1024)

#define  __EXEC_OBJECT_HAS_FENCE (1<<30)

/**
 * RC6 is a special power stage which allows the GPU to enter an very
 * low-voltage mode when idle, using down to 0V while at this stage.  This
 * stage is entered automatically when the GPU is idle when RC6 support is
 * enabled, and as soon as new workload arises GPU wakes up automatically as well.
 * 
 * There are different RC6 modes available in Intel GPU, which differentiate
 * among each other with the latency required to enter and leave RC6 and
 * voltage consumed by the GPU in different states.
 * 
 * The combination of the following flags define which states GPU is allowed
 * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and
 * RC6pp is deepest RC6. Their support by hardware varies according to the
 * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one
 * which brings the most power savings; deeper states save more power, but
 * require higher latency to switch to and wake up.
 */
#define INTEL_RC6_ENABLE			(1<<0)
#define INTEL_RC6p_ENABLE			(1<<1)
#define INTEL_RC6pp_ENABLE			(1<<2)

extern unsigned int i915_lvds_downclock;
extern int i915_panel_ignore_lid;
extern unsigned int i915_powersave;
extern int i915_semaphores;
extern int i915_enable_rc6;
extern int i915_enable_fbc;

/* Inlines */

/**
 * Returns true if seq1 is later than seq2.
 */
static __inline int
i915_seqno_passed(uint32_t seq1, uint32_t seq2)
{
	return ((int32_t)(seq1 - seq2) >= 0);
}

static inline bool
i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
{
	if (obj->fence_reg != I915_FENCE_REG_NONE) {
		drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
		dev_priv->fence_regs[obj->fence_reg].pin_count++;
		return true;
	} else
		return false;
}

static inline void
i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
{
	if (obj->fence_reg != I915_FENCE_REG_NONE) {
		drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
		dev_priv->fence_regs[obj->fence_reg].pin_count--;
	}
}

#if 0
static __inline int
i915_obj_purgeable(struct drm_i915_gem_object *obj_priv)
{
	return (obj_priv->base.do_flags & I915_DONTNEED);
}

static __inline int
i915_obj_purged(struct drm_i915_gem_object *obj_priv)
{
	return (obj_priv->base.do_flags & I915_PURGED);
}
#endif

static inline int
i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj)
{
	return obj->madv == I915_MADV_DONTNEED;
}

#endif