-
Notifications
You must be signed in to change notification settings - Fork 29
/
i915ovmf.c
executable file
·2818 lines (2525 loc) · 90.2 KB
/
i915ovmf.c
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
#include <Uefi.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/PciIo.h>
#include <Protocol/DriverSupportedEfiVersion.h>
#include <Protocol/DevicePath.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/FrameBufferBltLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include "QemuFwCfgLib.h"
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/Acpi.h>
//registers are in bar 0
//frame buffer is in bar 2
#define PCH_DISPLAY_BASE 0xc0000u
#define HSW_PWR_WELL_CTL1 (0x45400)
#define HSW_PWR_WELL_CTL2 (0x45404)
#define HSW_PWR_WELL_CTL3 (0x45408)
#define HSW_PWR_WELL_CTL4 (0x4540C)
#define GMBUS0 (PCH_DISPLAY_BASE+0x5100)
#define gmbusSelect (PCH_DISPLAY_BASE+0x5100)
#define GMBUS_AKSV_SELECT (1 << 11)
#define GMBUS_RATE_100KHZ (0 << 8)
#define GMBUS_RATE_50KHZ (1 << 8)
#define GMBUS_RATE_400KHZ (2 << 8) /* reserved on Pineview */
#define GMBUS_RATE_1MHZ (3 << 8) /* reserved on Pineview */
#define GMBUS_HOLD_EXT (1 << 7) /* 300ns hold time, rsvd on Pineview */
#define GMBUS_BYTE_CNT_OVERRIDE (1 << 6)
#define GMBUS_PIN_DISABLED 0
#define GMBUS_PIN_SSC 1
#define GMBUS_PIN_VGADDC 2
#define GMBUS_PIN_PANEL 3
#define GMBUS_PIN_DPD_CHV 3 /* HDMID_CHV */
#define GMBUS_PIN_DPC 4 /* HDMIC */
#define GMBUS_PIN_DPB 5 /* SDVO, HDMIB */
#define GMBUS_PIN_DPD 6 /* HDMID */
#define GMBUS_PIN_RESERVED 7 /* 7 reserved */
#define GMBUS_PIN_1_BXT 1 /* BXT+ (atom) and CNP+ (big core) */
#define GMBUS_PIN_2_BXT 2
#define GMBUS_PIN_3_BXT 3
#define GMBUS_PIN_4_CNP 4
#define GMBUS_PIN_9_TC1_ICP 9
#define GMBUS_PIN_10_TC2_ICP 10
#define GMBUS_PIN_11_TC3_ICP 11
#define GMBUS_PIN_12_TC4_ICP 12
#define gmbusCommand (PCH_DISPLAY_BASE+0x5104)
#define GMBUS_SW_CLR_INT (1 << 31)
#define GMBUS_SW_RDY (1 << 30)
#define GMBUS_ENT (1 << 29) /* enable timeout */
#define GMBUS_CYCLE_NONE (0 << 25)
#define GMBUS_CYCLE_WAIT (1 << 25)
#define GMBUS_CYCLE_INDEX (2 << 25)
#define GMBUS_CYCLE_STOP (4 << 25)
#define GMBUS_BYTE_COUNT_SHIFT 16
#define GMBUS_BYTE_COUNT_MAX 256U
#define GEN9_GMBUS_BYTE_COUNT_MAX 511U
#define GMBUS_SLAVE_INDEX_SHIFT 8
#define GMBUS_SLAVE_ADDR_SHIFT 1
#define GMBUS_SLAVE_READ (1 << 0)
#define GMBUS_SLAVE_WRITE (0 << 0)
#define gmbusStatus (PCH_DISPLAY_BASE+0x5108)
#define GMBUS_INUSE (1 << 15)
#define GMBUS_HW_WAIT_PHASE (1 << 14)
#define GMBUS_STALL_TIMEOUT (1 << 13)
#define GMBUS_INT (1 << 12)
#define GMBUS_HW_RDY (1 << 11)
#define GMBUS_SATOER (1 << 10)
#define GMBUS_ACTIVE (1 << 9)
#define gmbusData (PCH_DISPLAY_BASE+0x510C)
#define GMBUS4 (PCH_DISPLAY_BASE+0x5110)
#define _PCH_DP_B (0xe4100)
#define _PCH_DPB_AUX_CH_CTL (0xe4110)
#define _PCH_DPB_AUX_CH_DATA1 (0xe4114)
#define _PCH_DPB_AUX_CH_DATA2 (0xe4118)
#define _PCH_DPB_AUX_CH_DATA3 (0xe411c)
#define _PCH_DPB_AUX_CH_DATA4 (0xe4120)
#define _PCH_DPB_AUX_CH_DATA5 (0xe4124)
#define _DPA_AUX_CH_CTL (0x64010)
#define _DPA_AUX_CH_DATA1 (0x64014)
#define _DPA_AUX_CH_DATA2 (0x64018)
#define _DPA_AUX_CH_DATA3 (0x6401c)
#define _DPA_AUX_CH_DATA4 (0x64020)
#define _DPA_AUX_CH_DATA5 (0x64024)
#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31)
#define DP_AUX_CH_CTL_DONE (1 << 30)
#define DP_AUX_CH_CTL_INTERRUPT (1 << 29)
#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28)
#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26)
#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26)
#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26)
#define DP_AUX_CH_CTL_TIME_OUT_MAX (3 << 26) /* Varies per platform */
#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26)
#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25)
#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20)
#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20
#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16)
#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16
#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15)
#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14)
#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13)
#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12)
#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11)
#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff)
#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0
#define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14)
#define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13)
#define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12)
#define DP_AUX_CH_CTL_TBT_IO (1 << 11)
#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (0x1f << 5)
#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5)
#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1)
#define AUX_NATIVE_WRITE 0x8
#define AUX_NATIVE_READ 0x9
#define AUX_I2C_WRITE 0x0
#define AUX_I2C_READ 0x1
#define AUX_I2C_STATUS 0x2
#define AUX_I2C_MOT 0x4
#define AUX_I2C_REPLY_ACK 0x0
#define VGACNTRL (0x71400)
#define VGA_DISP_DISABLE (1 << 31)
#define VGA_2X_MODE (1 << 30)
/* Pipe A timing regs */
#define HTOTAL_A 0x60000
#define HBLANK_A 0x60004
#define HSYNC_A 0x60008
#define VTOTAL_A 0x6000c
#define VBLANK_A 0x60010
#define VSYNC_A 0x60014
#define PIPEASRC 0x6001c
#define BCLRPAT_A 0x60020
#define VSYNCSHIFT_A 0x60028
#define PIPE_MULT_A 0x6002c
/* Pipe B timing regs */
#define HTOTAL_B 0x61000
#define HBLANK_B 0x61004
#define HSYNC_B 0x61008
#define VTOTAL_B 0x6100c
#define VBLANK_B 0x61010
#define VSYNC_B 0x61014
#define PIPEBSRC 0x6101c
#define BCLRPAT_B 0x61020
#define VSYNCSHIFT_B 0x61028
#define PIPE_MULT_B 0x6102c
#define _PIPEACONF 0x70008
#define _PIPEBCONF 0x71008
#define PIPECONF_ENABLE (1 << 31)
#define PIPECONF_DISABLE 0
#define PIPECONF_DOUBLE_WIDE (1 << 30)
#define I965_PIPECONF_ACTIVE (1 << 30)
#define PIPECONF_DSI_PLL_LOCKED (1 << 29) /* vlv & pipe A only */
#define PIPECONF_FRAME_START_DELAY_MASK (3 << 27)
#define PIPECONF_SINGLE_WIDE 0
#define PIPECONF_PIPE_UNLOCKED 0
#define PIPECONF_PIPE_LOCKED (1 << 25)
#define PIPECONF_FORCE_BORDER (1 << 25)
#define PIPECONF_GAMMA_MODE_MASK_I9XX (1 << 24) /* gmch */
#define PIPECONF_GAMMA_MODE_MASK_ILK (3 << 24) /* ilk-ivb */
#define PIPECONF_GAMMA_MODE_8BIT (0 << 24) /* gmch,ilk-ivb */
#define PIPECONF_GAMMA_MODE_10BIT (1 << 24) /* gmch,ilk-ivb */
#define PIPECONF_GAMMA_MODE_12BIT (2 << 24) /* ilk-ivb */
#define PIPECONF_GAMMA_MODE_SPLIT (3 << 24) /* ivb */
#define PIPECONF_GAMMA_MODE(x) ((x) << 24) /* pass in GAMMA_MODE_MODE_* */
#define PIPECONF_GAMMA_MODE_SHIFT 24
#define PIPECONF_INTERLACE_MASK (7 << 21)
#define PIPECONF_INTERLACE_MASK_HSW (3 << 21)
/* Note that pre-gen3 does not support interlaced display directly. Panel
* fitting must be disabled on pre-ilk for interlaced. */
#define PIPECONF_PROGRESSIVE (0 << 21)
#define PIPECONF_INTERLACE_W_SYNC_SHIFT_PANEL (4 << 21) /* gen4 only */
#define PIPECONF_INTERLACE_W_SYNC_SHIFT (5 << 21) /* gen4 only */
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) /* gen3 only */
/* Ironlake and later have a complete new set of values for interlaced. PFIT
* means panel fitter required, PF means progressive fetch, DBL means power
* saving pixel doubling. */
#define PIPECONF_PFIT_PF_INTERLACED_ILK (1 << 21)
#define PIPECONF_INTERLACED_ILK (3 << 21)
#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */
#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */
#define PIPECONF_INTERLACE_MODE_MASK (7 << 21)
#define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20)
#define PIPECONF_CXSR_DOWNCLOCK (1 << 16)
#define PIPECONF_EDP_RR_MODE_SWITCH_VLV (1 << 14)
#define PIPECONF_COLOR_RANGE_SELECT (1 << 13)
#define PIPECONF_BPC_MASK (0x7 << 5)
#define PIPECONF_8BPC (0 << 5)
#define PIPECONF_10BPC (1 << 5)
#define PIPECONF_6BPC (2 << 5)
#define PIPECONF_12BPC (3 << 5)
#define PIPECONF_DITHER_EN (1 << 4)
#define PIPECONF_DITHER_TYPE_MASK (0x0000000c)
#define PIPECONF_DITHER_TYPE_SP (0 << 2)
#define PIPECONF_DITHER_TYPE_ST1 (1 << 2)
#define PIPECONF_DITHER_TYPE_ST2 (2 << 2)
#define PIPECONF_DITHER_TYPE_TEMP (3 << 2)
#define _PIPEASTAT 0x70024
#define _PIPEBSTAT 0x71024
#define PIPE_FIFO_UNDERRUN_STATUS (1UL << 31)
#define SPRITE1_FLIP_DONE_INT_EN_VLV (1UL << 30)
#define PIPE_CRC_ERROR_ENABLE (1UL << 29)
#define PIPE_CRC_DONE_ENABLE (1UL << 28)
#define PERF_COUNTER2_INTERRUPT_EN (1UL << 27)
#define PIPE_GMBUS_EVENT_ENABLE (1UL << 27)
#define PLANE_FLIP_DONE_INT_EN_VLV (1UL << 26)
#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL << 26)
#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL << 25)
#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL << 24)
#define PIPE_DPST_EVENT_ENABLE (1UL << 23)
#define SPRITE0_FLIP_DONE_INT_EN_VLV (1UL << 22)
#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL << 22)
#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL << 21)
#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL << 20)
#define PIPE_B_PSR_INTERRUPT_ENABLE_VLV (1UL << 19)
#define PERF_COUNTER_INTERRUPT_EN (1UL << 19)
#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL << 18) /* pre-965 */
#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18) /* 965 or later */
#define PIPE_FRAMESTART_INTERRUPT_ENABLE (1UL << 17)
#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17)
#define PIPEA_HBLANK_INT_EN_VLV (1UL << 16)
#define PIPE_OVERLAY_UPDATED_ENABLE (1UL << 16)
#define SPRITE1_FLIP_DONE_INT_STATUS_VLV (1UL << 15)
#define SPRITE0_FLIP_DONE_INT_STATUS_VLV (1UL << 14)
#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL << 13)
#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL << 12)
#define PERF_COUNTER2_INTERRUPT_STATUS (1UL << 11)
#define PIPE_GMBUS_INTERRUPT_STATUS (1UL << 11)
#define PLANE_FLIP_DONE_INT_STATUS_VLV (1UL << 10)
#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL << 10)
#define PIPE_VSYNC_INTERRUPT_STATUS (1UL << 9)
#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL << 8)
#define PIPE_DPST_EVENT_STATUS (1UL << 7)
#define PIPE_A_PSR_STATUS_VLV (1UL << 6)
#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL << 6)
#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL << 5)
#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL << 4)
#define PIPE_B_PSR_STATUS_VLV (1UL << 3)
#define PERF_COUNTER_INTERRUPT_STATUS (1UL << 3)
#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL << 2) /* pre-965 */
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL << 2) /* 965 or later */
#define PIPE_FRAMESTART_INTERRUPT_STATUS (1UL << 1)
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1)
#define PIPE_HBLANK_INT_STATUS (1UL << 0)
#define PIPE_OVERLAY_UPDATED_STATUS (1UL << 0)
#define _DSPACNTR 0x70180
#define DISPLAY_PLANE_ENABLE (1 << 31)
#define DISPLAY_PLANE_DISABLE 0
#define PLANE_CTL_FORMAT_MASK (0xf << 24)
#define PLANE_CTL_FORMAT_YUV422 (0 << 24)
#define PLANE_CTL_FORMAT_NV12 (1 << 24)
#define PLANE_CTL_FORMAT_XRGB_2101010 (2 << 24)
#define PLANE_CTL_FORMAT_XRGB_8888 (4 << 24)
#define PLANE_CTL_ORDER_BGRX (0 << 20)
#define PLANE_CTL_ORDER_RGBX (1 << 20)
#define PLANE_CTL_ALPHA_MASK (0x3 << 4) /* Pre-GLK */
#define PLANE_CTL_ALPHA_DISABLE (0 << 4)
#define PLANE_CTL_ALPHA_SW_PREMULTIPLY (2 << 4)
#define PLANE_CTL_ALPHA_HW_PREMULTIPLY (3 << 4)
#define PLANE_CTL_TRICKLE_FEED_DISABLE (1 << 14)
#define PLANE_CTL_PLANE_GAMMA_DISABLE (1 << 13) /* Pre-GLK */
#define DISPPLANE_PIXFORMAT_MASK (0xf << 26)
#define DISPPLANE_YUV422 (0x0 << 26)
#define DISPPLANE_8BPP (0x2 << 26)
#define DISPPLANE_BGRA555 (0x3 << 26)
#define DISPPLANE_BGRX555 (0x4 << 26)
#define DISPPLANE_BGRX565 (0x5 << 26)
#define DISPPLANE_BGRX888 (0x6 << 26)
#define DISPPLANE_BGRA888 (0x7 << 26)
#define DISPPLANE_RGBX101010 (0x8 << 26)
#define DISPPLANE_RGBA101010 (0x9 << 26)
#define DISPPLANE_BGRX101010 (0xa << 26)
#define DISPPLANE_RGBX161616 (0xc << 26)
#define DISPPLANE_RGBX888 (0xe << 26)
#define DISPPLANE_RGBA888 (0xf << 26)
#define _DSPAADDR 0x70184
#define _DSPASTRIDE 0x70188
#define _DSPAPOS 0x7018C /* reserved */
#define _DSPASIZE 0x70190
#define _DSPASURF 0x7019C /* 965+ only */
#define _DSPATILEOFF 0x701A4 /* 965+ only */
#define _DSPAOFFSET 0x701A4 /* HSW */
#define _DSPASURFLIVE 0x701AC
#define _TRANSA_MSA_MISC 0x60410
#define _TRANSB_MSA_MISC 0x61410
#define _TRANSC_MSA_MISC 0x62410
#define _TRANS_EDP_MSA_MISC 0x6f410
#define TRANS_MSA_SYNC_CLK (1 << 0)
#define TRANS_MSA_SAMPLING_444 (2 << 1)
#define TRANS_MSA_CLRSP_YCBCR (2 << 3)
#define TRANS_MSA_6_BPC (0 << 5)
#define TRANS_MSA_8_BPC (1 << 5)
#define TRANS_MSA_10_BPC (2 << 5)
#define TRANS_MSA_12_BPC (3 << 5)
#define TRANS_MSA_16_BPC (4 << 5)
#define TRANS_MSA_CEA_RANGE (1 << 3)
#define _TRANS_DDI_FUNC_CTL_A 0x60400
#define _TRANS_DDI_FUNC_CTL_B 0x61400
#define _TRANS_DDI_FUNC_CTL_C 0x62400
#define _TRANS_DDI_FUNC_CTL_EDP 0x6F400
#define _TRANS_DDI_FUNC_CTL_DSI0 0x6b400
#define _TRANS_DDI_FUNC_CTL_DSI1 0x6bc00
#define TRANS_DDI_FUNC_ENABLE (1 << 31)
/* Those bits are ignored by pipe EDP since it can only connect to DDI A */
#define TRANS_DDI_PORT_MASK (7 << 28)
#define TRANS_DDI_PORT_SHIFT 28
#define TRANS_DDI_SELECT_PORT(x) ((x) << 28)
#define TRANS_DDI_PORT_NONE (0 << 28)
#define TRANS_DDI_MODE_SELECT_MASK (7 << 24)
#define TRANS_DDI_MODE_SELECT_HDMI (0 << 24)
#define TRANS_DDI_MODE_SELECT_DVI (1 << 24)
#define TRANS_DDI_MODE_SELECT_DP_SST (2 << 24)
#define TRANS_DDI_MODE_SELECT_DP_MST (3 << 24)
#define TRANS_DDI_MODE_SELECT_FDI (4 << 24)
#define TRANS_DDI_BPC_MASK (7 << 20)
#define TRANS_DDI_BPC_8 (0 << 20)
#define TRANS_DDI_BPC_10 (1 << 20)
#define TRANS_DDI_BPC_6 (2 << 20)
#define TRANS_DDI_BPC_12 (3 << 20)
#define TRANS_DDI_PVSYNC (1 << 17)
#define TRANS_DDI_PHSYNC (1 << 16)
#define TRANS_DDI_EDP_INPUT_MASK (7 << 12)
#define TRANS_DDI_EDP_INPUT_A_ON (0 << 12)
#define TRANS_DDI_EDP_INPUT_A_ONOFF (4 << 12)
#define TRANS_DDI_EDP_INPUT_B_ONOFF (5 << 12)
#define TRANS_DDI_EDP_INPUT_C_ONOFF (6 << 12)
#define TRANS_DDI_HDCP_SIGNALLING (1 << 9)
#define TRANS_DDI_DP_VC_PAYLOAD_ALLOC (1 << 8)
#define TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE (1 << 7)
#define TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ (1 << 6)
#define TRANS_DDI_BFI_ENABLE (1 << 4)
#define TRANS_DDI_HIGH_TMDS_CHAR_RATE (1 << 4)
#define TRANS_DDI_HDMI_SCRAMBLING (1 << 0)
#define TRANS_DDI_HDMI_SCRAMBLING_MASK (TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE \
| TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ \
| TRANS_DDI_HDMI_SCRAMBLING)
#define _TRANS_DDI_FUNC_CTL2_A 0x60404
#define _TRANS_DDI_FUNC_CTL2_B 0x61404
#define _TRANS_DDI_FUNC_CTL2_C 0x62404
#define _TRANS_DDI_FUNC_CTL2_EDP 0x6f404
#define _TRANS_DDI_FUNC_CTL2_DSI0 0x6b404
#define _TRANS_DDI_FUNC_CTL2_DSI1 0x6bc04
#define PORT_SYNC_MODE_ENABLE (1 << 4)
#define PORT_SYNC_MODE_MASTER_SELECT(x) ((x) < 0)
#define PORT_SYNC_MODE_MASTER_SELECT_MASK (0x7 << 0)
#define PORT_SYNC_MODE_MASTER_SELECT_SHIFT 0
#define PORT_A 0
#define PORT_B 1
#define PORT_C 2
#define PORT_D 3
#define PORT_E 4
#define _FPA0 (PCH_DISPLAY_BASE+0x6040)
#define _FPA1 (PCH_DISPLAY_BASE+0x6044)
#define _FPB0 (PCH_DISPLAY_BASE+0x6048)
#define _FPB1 (PCH_DISPLAY_BASE+0x604c)
#define FP_N_DIV_MASK 0x003f0000
#define FP_N_PINEVIEW_DIV_MASK 0x00ff0000
#define FP_N_DIV_SHIFT 16
#define FP_M1_DIV_MASK 0x00003f00
#define FP_M1_DIV_SHIFT 8
#define FP_M2_DIV_MASK 0x0000003f
#define FP_M2_PINEVIEW_DIV_MASK 0x000000ff
#define FP_M2_DIV_SHIFT 0
#define _DPLL_A (PCH_DISPLAY_BASE + 0x6014)
#define _DPLL_B (PCH_DISPLAY_BASE + 0x6018)
#define DPLL_VCO_ENABLE (1 << 31)
#define DPLL_SDVO_HIGH_SPEED (1 << 30)
#define DPLL_DVO_2X_MODE (1 << 30)
#define DPLL_EXT_BUFFER_ENABLE_VLV (1 << 30)
#define DPLL_SYNCLOCK_ENABLE (1 << 29)
#define DPLL_REF_CLK_ENABLE_VLV (1 << 29)
#define DPLL_VGA_MODE_DIS (1 << 28)
#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
#define DPLL_MODE_MASK (3 << 26)
#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */
#define DPLL_LOCK_VLV (1 << 15)
#define DPLL_INTEGRATED_CRI_CLK_VLV (1 << 14)
#define DPLL_INTEGRATED_REF_CLK_VLV (1 << 13)
#define DPLL_SSC_REF_CLK_CHV (1 << 13)
#define DPLL_PORTC_READY_MASK (0xf << 4)
#define DPLL_PORTB_READY_MASK (0xf)
#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
#define DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15
#define PLL_P2_DIVIDE_BY_4 (1 << 23)
#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
#define PLL_REF_INPUT_DREFCLK (0 << 13)
#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
#define PLL_REF_INPUT_MASK (3 << 13)
#define PLL_LOAD_PULSE_PHASE_SHIFT 9
/* Ironlake */
#define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9
#define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9)
#define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x) - 1) << 9)
#define DPLL_FPA1_P1_POST_DIV_SHIFT 0
#define DPLL_FPA1_P1_POST_DIV_MASK 0xff
#define _DPLL_A_MD (PCH_DISPLAY_BASE + 0x601c)
#define _DPLL_B_MD (PCH_DISPLAY_BASE + 0x6020)
#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
/*
* SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
* This best be set to the default value (3) or the CRT won't work. No,
* I don't entirely understand what this does...
*/
#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
#define DPLL_CTRL2 (0x6C05C)
#define DPLL_CTRL2_DDI_CLK_OFF(port) (1 << ((port) + 15))
#define DPLL_CTRL2_DDI_CLK_SEL_MASK(port) (3 << ((port) * 3 + 1))
#define DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port) ((port) * 3 + 1)
#define DPLL_CTRL2_DDI_CLK_SEL(clk, port) ((clk) << ((port) * 3 + 1))
#define DPLL_CTRL2_DDI_SEL_OVERRIDE(port) (1 << ((port) * 3))
#define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))
#define _PORT(port, a, b) _PICK_EVEN(port, a, b)
#define _DDI_BUF_TRANS_A 0x64E00
#define _DDI_BUF_TRANS_B 0x64E60
#define DDI_BUF_TRANS_LO(port, i) (_PORT(port, _DDI_BUF_TRANS_A,_DDI_BUF_TRANS_B) + (i) * 8)
#define DDI_BUF_BALANCE_LEG_ENABLE (1 << 31)
#define DDI_BUF_TRANS_HI(port, i) (_PORT(port, _DDI_BUF_TRANS_A,_DDI_BUF_TRANS_B) + (i) * 8 + 4)
#define DISPIO_CR_TX_BMU_CR0 (0x6C00C)
/* I_boost values */
#define BALANCE_LEG_SHIFT(port) (8 + 3 * (port))
#define BALANCE_LEG_MASK(port) (7 << (8 + 3 * (port)))
/* Balance leg disable bits */
#define BALANCE_LEG_DISABLE_SHIFT 23
#define BALANCE_LEG_DISABLE(port) (1 << (23 + (port)))
#define _TRANS_CLK_SEL_A 0x46140
#define _TRANS_CLK_SEL_B 0x46144
/* For each transcoder, we need to select the corresponding port clock */
#define TRANS_CLK_SEL_DISABLED (0x0 << 29)
#define TRANS_CLK_SEL_PORT(x) (((x) + 1) << 29)
#define _LGC_PALETTE_A 0x4a000
#define _LGC_PALETTE_B 0x4a800
#define _SKL_BOTTOM_COLOR_A 0x70034
#define SKL_BOTTOM_COLOR_GAMMA_ENABLE (1 << 31)
#define SKL_BOTTOM_COLOR_CSC_ENABLE (1 << 30)
#define _GAMMA_MODE_A 0x4a480
#define _GAMMA_MODE_B 0x4ac80
#define PRE_CSC_GAMMA_ENABLE (1 << 31)
#define POST_CSC_GAMMA_ENABLE (1 << 30)
#define GAMMA_MODE_MODE_8BIT (0 << 0)
#define GAMMA_MODE_MODE_10BIT (1 << 0)
#define GAMMA_MODE_MODE_12BIT (2 << 0)
#define GAMMA_MODE_MODE_SPLIT (3 << 0)
#define SFUSE_STRAP (0xc2014)
#define SFUSE_STRAP_FUSE_LOCK (1 << 13)
#define SFUSE_STRAP_RAW_FREQUENCY (1 << 8)
#define SFUSE_STRAP_DISPLAY_DISABLED (1 << 7)
#define SFUSE_STRAP_CRT_DISABLED (1 << 6)
#define SFUSE_STRAP_DDIF_DETECTED (1 << 3)
#define SFUSE_STRAP_DDIB_DETECTED (1 << 2)
#define SFUSE_STRAP_DDIC_DETECTED (1 << 1)
#define SFUSE_STRAP_DDID_DETECTED (1 << 0)
#define _DDI_BUF_CTL_A 0x64000
#define _DDI_BUF_CTL_B 0x64100
#define DDI_BUF_CTL(port) _PORT(port, _DDI_BUF_CTL_A, _DDI_BUF_CTL_B)
#define DDI_BUF_CTL_ENABLE (1 << 31)
#define DDI_BUF_TRANS_SELECT(n) ((n) << 24)
#define DDI_BUF_EMP_MASK (0xf << 24)
#define DDI_BUF_PORT_REVERSAL (1 << 16)
#define DDI_BUF_IS_IDLE (1 << 7)
#define DDI_A_4_LANES (1 << 4)
#define DDI_PORT_WIDTH(width) (((width) - 1) << 1)
#define DDI_PORT_WIDTH_MASK (7 << 1)
#define DDI_PORT_WIDTH_SHIFT 1
#define DDI_INIT_DISPLAY_DETECTED (1 << 0)
#define CHICKEN_TRANS_A (0x420c0)
#define CHICKEN_TRANS_B (0x420c4)
#define CHICKEN_TRANS_C (0x420c8)
#define CHICKEN_TRANS_EDP (0x420cc)
#define VSC_DATA_SEL_SOFTWARE_CONTROL (1 << 25) /* GLK and CNL+ */
#define DDI_TRAINING_OVERRIDE_ENABLE (1 << 19)
#define DDI_TRAINING_OVERRIDE_VALUE (1 << 18)
#define DDIE_TRAINING_OVERRIDE_ENABLE (1 << 17) /* CHICKEN_TRANS_A only */
#define DDIE_TRAINING_OVERRIDE_VALUE (1 << 16) /* CHICKEN_TRANS_A only */
#define PSR2_ADD_VERTICAL_LINE_COUNT (1 << 15)
#define PSR2_VSC_ENABLE_PROG_HEADER (1 << 12)
#define HSW_NDE_RSTWRN_OPT (0x46408)
#define RESET_PCH_HANDSHAKE_ENABLE (1 << 4)
#define CDCLK_CTL (0x46000)
#define CDCLK_FREQ_SEL_MASK (3 << 26)
#define CDCLK_FREQ_450_432 (0 << 26)
#define CDCLK_FREQ_540 (1 << 26)
#define CDCLK_FREQ_337_308 (2 << 26)
#define CDCLK_FREQ_675_617 (3 << 26)
#define BXT_CDCLK_CD2X_DIV_SEL_MASK (3 << 22)
#define BXT_CDCLK_CD2X_DIV_SEL_1 (0 << 22)
#define BXT_CDCLK_CD2X_DIV_SEL_1_5 (1 << 22)
#define BXT_CDCLK_CD2X_DIV_SEL_2 (2 << 22)
#define BXT_CDCLK_CD2X_DIV_SEL_4 (3 << 22)
#define BXT_CDCLK_CD2X_PIPE(pipe) ((pipe) << 20)
#define CDCLK_DIVMUX_CD_OVERRIDE (1 << 19)
#define BXT_CDCLK_CD2X_PIPE_NONE BXT_CDCLK_CD2X_PIPE(3)
#define ICL_CDCLK_CD2X_PIPE_NONE (7 << 19)
#define BXT_CDCLK_SSA_PRECHARGE_ENABLE (1 << 16)
#define CDCLK_FREQ_DECIMAL_MASK (0x7ff)
#define DBUF_CTL (0x45008)
#define DBUF_CTL_S1 (0x45008)
#define DBUF_CTL_S2 (0x44FE8)
#define DBUF_POWER_REQUEST (1 << 31)
#define DBUF_POWER_STATE (1 << 30)
#define MBUS_ABOX_CTL (0x45038)
#define MBUS_ABOX_BW_CREDIT_MASK (3 << 20)
#define MBUS_ABOX_BW_CREDIT(x) ((x) << 20)
#define MBUS_ABOX_B_CREDIT_MASK (0xF << 16)
#define MBUS_ABOX_B_CREDIT(x) ((x) << 16)
#define MBUS_ABOX_BT_CREDIT_POOL2_MASK (0x1F << 8)
#define MBUS_ABOX_BT_CREDIT_POOL2(x) ((x) << 8)
#define MBUS_ABOX_BT_CREDIT_POOL1_MASK (0x1F << 0)
#define MBUS_ABOX_BT_CREDIT_POOL1(x) ((x) << 0)
#define _PLANE_BUF_CFG_1_A 0x7027c
#define I915_READ read32
#define I915_WRITE write32
STATIC EFI_GRAPHICS_OUTPUT_MODE_INFORMATION g_mode_info[] = {
{
0, // Version
1024, // HorizontalResolution
768, // VerticalResolution
}
};
STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE g_mode = {
ARRAY_SIZE (g_mode_info), // MaxMode
0, // Mode
g_mode_info, // Info
sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), // SizeOfInfo
};
#pragma pack(1)
typedef struct {
UINT8 magic[8];
UINT16 vendorId;
UINT16 productId;
UINT32 serialNumber;
UINT8 manufactureWeek;
UINT8 manufactureYear;
UINT8 structVersion;
UINT8 structRevision;
UINT8 inputParameters;
UINT8 screenWidth;
UINT8 screenHeight;
UINT8 gamma;
UINT8 features;
UINT8 colorCoordinates[10];
UINT8 estTimings1;
UINT8 estTimings2;
UINT8 vendorTimings;
struct {
UINT8 resolution;
UINT8 frequency;
} standardTimings[8];
struct {
UINT16 pixelClock;
UINT8 horzActive;
UINT8 horzBlank;
UINT8 horzActiveBlankMsb;
UINT8 vertActive;
UINT8 vertBlank;
UINT8 vertActiveBlankMsb;
UINT8 horzSyncOffset;
UINT8 horzSyncPulse;
UINT8 vertSync;
UINT8 syncMsb;
UINT8 dimensionWidth;
UINT8 dimensionHeight;
UINT8 dimensionMsb;
UINT8 horzBorder;
UINT8 vertBorder;
UINT8 features;
} detailTimings[4];
UINT8 numExtensions;
UINT8 checksum;
} EDID;
#pragma pack()
typedef struct {
UINT64 Signature;
EFI_HANDLE Handle;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
EDID edid;
EFI_PHYSICAL_ADDRESS FbBase;
UINT32 stride;
UINT32 gmadr;
UINT32 is_gvt;
} I915_VIDEO_PRIVATE_DATA;
I915_VIDEO_PRIVATE_DATA g_private={SIGNATURE_32('i','9','1','5')};
static void write32(UINT64 reg, UINT32 data){
g_private.PciIo->Mem.Write (
g_private.PciIo,
EfiPciIoWidthFillUint32,
PCI_BAR_IDX0,
reg,
1,
&data
);
}
static UINT32 read32(UINT64 reg){
UINT32 data=0;
g_private.PciIo->Mem.Read (
g_private.PciIo,
EfiPciIoWidthFillUint32,
PCI_BAR_IDX0,
reg,
1,
&data
);
return data;
}
static UINT64 read64(UINT64 reg){
UINT64 data=0;
g_private.PciIo->Mem.Read (
g_private.PciIo,
EfiPciIoWidthFillUint64,
PCI_BAR_IDX0,
reg,
1,
&data
);
return data;
}
static EFI_STATUS gmbusWait(UINT32 wanted){
UINTN counter=0;
for(;;){
UINT32 status=read32(gmbusStatus);
counter+=1;
if(counter>=1024){
//failed
DebugPrint(EFI_D_ERROR,"i915: gmbus timeout\n");
return EFI_DEVICE_ERROR;
}
if(status&GMBUS_SATOER){
//failed
DebugPrint(EFI_D_ERROR,"i915: gmbus error\n");
return EFI_DEVICE_ERROR;
}
if(status&wanted){
//worked
return EFI_SUCCESS;
}
}
}
static EFI_STATUS ReadEDID(EDID* result){
UINT32 pin=0;
//it's an INTEL GPU, there's no way we could be big endian
UINT32* p=(UINT32*)result;
//try all the pins on GMBUS
for(pin=1;pin<=6;pin++){
DebugPrint(EFI_D_ERROR,"i915: trying pin %d\n",pin);
write32(gmbusSelect, pin);
if(EFI_ERROR(gmbusWait(GMBUS_HW_RDY))){
//it's DP, need to hack AUX_CHAN
continue;
}
//set read offset: i2cWrite(0x50, &offset, 1);
write32(gmbusData, 0);
write32(gmbusCommand, (0x50<<GMBUS_SLAVE_ADDR_SHIFT)|(1<<GMBUS_BYTE_COUNT_SHIFT)|GMBUS_SLAVE_WRITE|GMBUS_CYCLE_WAIT|GMBUS_SW_RDY);
//gmbusWait(GMBUS_HW_WAIT_PHASE);
gmbusWait(GMBUS_HW_RDY);
//read the edid: i2cRead(0x50, &edid, 128);
//note that we could fail here!
write32(gmbusCommand, (0x50<<GMBUS_SLAVE_ADDR_SHIFT)|(128<<GMBUS_BYTE_COUNT_SHIFT)|GMBUS_SLAVE_READ|GMBUS_CYCLE_WAIT|GMBUS_SW_RDY);
UINT32 i=0;
for(i=0;i<128;i+=4){
if(EFI_ERROR(gmbusWait(GMBUS_HW_RDY))){break;}
p[i>>2]=read32(gmbusData);
}
//gmbusWait(GMBUS_HW_WAIT_PHASE);
gmbusWait(GMBUS_HW_RDY);
for(UINT32 i=0;i<16;i++){
for(UINT32 j=0;j<8;j++){
DebugPrint(EFI_D_ERROR,"%02x ",((UINT8*)(p))[i*8+j]);
}
DebugPrint(EFI_D_ERROR,"\n");
}
if(i>=128&&*(UINT64*)result->magic==0x00FFFFFFFFFFFF00uLL){return EFI_SUCCESS;}
}
//try DP AUX CHAN - Skylake
//write32(_DPA_AUX_CH_CTL+(1<<8),0x1234)
//write32(_DPA_AUX_CH_CTL+(0x600),0x1234);
//write32(_DPA_AUX_CH_CTL+(0<<8),0x1234);
//write32(_DPA_AUX_CH_DATA1+(0<<8),0xabcd);
//write32(_DPA_AUX_CH_DATA2+(0<<8),0xabcd);
//write32(_DPA_AUX_CH_DATA3+(0<<8),0xabcd);
//DebugPrint(EFI_D_ERROR,"i915: SKL CTL %08x\n",read32(_DPA_AUX_CH_CTL+(0<<8)));
//DebugPrint(EFI_D_ERROR,"i915: SKL DATA %08x\n",read32(_DPA_AUX_CH_DATA1+(0<<8)));
//DebugPrint(EFI_D_ERROR,"i915: SKL DATA %08x\n",read32(_DPA_AUX_CH_DATA2+(0<<8)));
//DebugPrint(EFI_D_ERROR,"i915: SKL DATA %08x\n",read32(_DPA_AUX_CH_DATA3+(0<<8)));
//write32(_PCH_DP_B+(1<<8),0x1234);
//DebugPrint(EFI_D_ERROR,"i915: SKL %08x\n",read32(_DPA_AUX_CH_CTL+(1<<8)));
//DebugPrint(EFI_D_ERROR,"i915: PCH %08x\n",read32(_PCH_DP_B+(1<<8)));
for(pin=0;pin<=5;pin++){
DebugPrint(EFI_D_ERROR,"i915: trying DP aux %d\n",pin);
//aux message header is 3-4 bytes: ctrl8 addr16 len8
//the data is big endian
//len is receive buffer size-1
//i2c init
UINT32 send_ctl=(
DP_AUX_CH_CTL_SEND_BUSY |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_TIME_OUT_MAX |
DP_AUX_CH_CTL_RECEIVE_ERROR |
(3 << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
DP_AUX_CH_CTL_SYNC_PULSE_SKL(32)
);
/* Must try at least 3 times according to DP spec, WHICH WE DON'T CARE */
write32(_DPA_AUX_CH_DATA1+(pin<<8), ((AUX_I2C_MOT|AUX_I2C_WRITE)<<28)|(0x50<<8)|0);
write32(_DPA_AUX_CH_CTL+(pin<<8), send_ctl);
UINT32 aux_status;
UINT32 counter=0;
for(;;){
aux_status=read32(_DPA_AUX_CH_CTL+(pin<<8));
if(!(aux_status&DP_AUX_CH_CTL_SEND_BUSY)){break;}
counter+=1;
if(counter>=16384){
DebugPrint(EFI_D_ERROR,"i915:DP AUX channel timeout");
break;
}
}
write32(_DPA_AUX_CH_CTL+(pin<<8),
aux_status |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_RECEIVE_ERROR
);
//i2c send 1 byte
send_ctl=(
DP_AUX_CH_CTL_SEND_BUSY |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_TIME_OUT_MAX |
DP_AUX_CH_CTL_RECEIVE_ERROR |
(5 << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
DP_AUX_CH_CTL_SYNC_PULSE_SKL(32)
);
write32(_DPA_AUX_CH_DATA1+(pin<<8), (AUX_I2C_WRITE<<28)|(0x50<<8)|0);
write32(_DPA_AUX_CH_DATA2+(pin<<8), 0);
write32(_DPA_AUX_CH_CTL+(pin<<8), send_ctl);
counter=0;
for(;;){
aux_status=read32(_DPA_AUX_CH_CTL+(pin<<8));
if(!(aux_status&DP_AUX_CH_CTL_SEND_BUSY)){break;}
counter+=1;
if(counter>=16384){
DebugPrint(EFI_D_ERROR,"i915:DP AUX channel timeout");
break;
}
}
write32(_DPA_AUX_CH_CTL+(pin<<8),
aux_status |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_RECEIVE_ERROR
);
if (aux_status & (DP_AUX_CH_CTL_TIME_OUT_ERROR|DP_AUX_CH_CTL_RECEIVE_ERROR)){
continue;
}
//i2c read 1 byte * 128
DebugPrint(EFI_D_ERROR,"i915: reading DP aux %d\n",pin);
//aux message header is 3-4 bytes: ctrl8 addr16 len8
//the data is big endian
//len is receive buffer size-1
//i2c init
send_ctl=(
DP_AUX_CH_CTL_SEND_BUSY |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_TIME_OUT_MAX |
DP_AUX_CH_CTL_RECEIVE_ERROR |
(3 << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
DP_AUX_CH_CTL_SYNC_PULSE_SKL(32)
);
/* Must try at least 3 times according to DP spec, WHICH WE DON'T CARE */
write32(_DPA_AUX_CH_DATA1+(pin<<8), ((AUX_I2C_MOT|AUX_I2C_READ)<<28)|(0x50<<8)|0);
write32(_DPA_AUX_CH_CTL+(pin<<8), send_ctl);
counter=0;
for(;;){
aux_status=read32(_DPA_AUX_CH_CTL+(pin<<8));
if(!(aux_status&DP_AUX_CH_CTL_SEND_BUSY)){break;}
counter+=1;
if(counter>=16384){
DebugPrint(EFI_D_ERROR,"i915: DP AUX channel timeout");
break;
}
}
write32(_DPA_AUX_CH_CTL+(pin<<8),
aux_status |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_RECEIVE_ERROR
);
UINT32 i=0;
for(i=0;i<128;i++){
send_ctl=(
DP_AUX_CH_CTL_SEND_BUSY |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_TIME_OUT_MAX |
DP_AUX_CH_CTL_RECEIVE_ERROR |
(4 << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
DP_AUX_CH_CTL_SYNC_PULSE_SKL(32)
);
write32(_DPA_AUX_CH_DATA1+(pin<<8), (AUX_I2C_READ<<28)|(0x50<<8)|0);
write32(_DPA_AUX_CH_CTL+(pin<<8), send_ctl);
counter=0;
for(;;){
aux_status=read32(_DPA_AUX_CH_CTL+(pin<<8));
if(!(aux_status&DP_AUX_CH_CTL_SEND_BUSY)){break;}
counter+=1;
if(counter>=16384){
DebugPrint(EFI_D_ERROR,"i915: DP AUX channel timeout");
break;
}
}
write32(_DPA_AUX_CH_CTL+(pin<<8),
aux_status |
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_RECEIVE_ERROR
);
UINT32 word=read32(_DPA_AUX_CH_DATA1+(pin<<8));
((UINT8*)p)[i]=(word>>16)&0xff;
}
for(UINT32 i=0;i<16;i++){
for(UINT32 j=0;j<8;j++){
DebugPrint(EFI_D_ERROR,"%02x ",((UINT8*)(p))[i*8+j]);
}
DebugPrint(EFI_D_ERROR,"\n");
}
if(i>=128&&*(UINT64*)result->magic==0x00FFFFFFFFFFFF00uLL){return EFI_SUCCESS;}
}
return EFI_NOT_FOUND;
}
STATIC EFI_STATUS EFIAPI i915GraphicsOutputQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
{
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo;
DebugPrint(EFI_D_ERROR,"i915: query mode\n");
if (Info == NULL || SizeOfInfo == NULL ||
ModeNumber >= g_mode.MaxMode) {
return EFI_INVALID_PARAMETER;
}
ModeInfo = &g_mode_info[ModeNumber];
*Info = AllocateCopyPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), ModeInfo);
if (*Info == NULL) {
return EFI_OUT_OF_RESOURCES;
}
*SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
return EFI_SUCCESS;
}
STATIC FRAME_BUFFER_CONFIGURE *g_i915FrameBufferBltConfigure=NULL;
STATIC UINTN g_i915FrameBufferBltConfigureSize=0;
STATIC INTN g_already_set=0;
struct dpll {
/* given values */
int n;
int m1, m2;
int p1, p2;
/* derived values */
int dot;
int vco;
int m;
int p;
};
struct intel_limit {
struct {
int min, max;
} dot, vco, n, m, m1, m2, p, p1;
struct {
int dot_limit;
int p2_slow, p2_fast;
} p2;
};
//intel_limits_i9xx_sdvo
//static const struct intel_limit g_limits = {
// .dot = { .min = 20000, .max = 400000 },
// .vco = { .min = 1400000, .max = 2800000 },
// .n = { .min = 1, .max = 6 },
// .m = { .min = 70, .max = 120 },
// .m1 = { .min = 8, .max = 18 },
// .m2 = { .min = 3, .max = 7 },
// .p = { .min = 5, .max = 80 },
// .p1 = { .min = 1, .max = 8 },
// .p2 = { .dot_limit = 200000,
// .p2_slow = 10, .p2_fast = 5 },
//};
#define DPLL_CTRL1 (0x6C058)
#define DPLL_CTRL1_HDMI_MODE(id) (1 << ((id) * 6 + 5))
#define DPLL_CTRL1_SSC(id) (1 << ((id) * 6 + 4))
#define DPLL_CTRL1_LINK_RATE_MASK(id) (7 << ((id) * 6 + 1))
#define DPLL_CTRL1_LINK_RATE_SHIFT(id) ((id) * 6 + 1)
#define DPLL_CTRL1_LINK_RATE(linkrate, id) ((linkrate) << ((id) * 6 + 1))
#define DPLL_CTRL1_OVERRIDE(id) (1 << ((id) * 6))
#define DPLL_CTRL1_LINK_RATE_2700 0
#define DPLL_CTRL1_LINK_RATE_1350 1
#define DPLL_CTRL1_LINK_RATE_810 2
#define DPLL_CTRL1_LINK_RATE_1620 3
#define DPLL_CTRL1_LINK_RATE_1080 4
#define DPLL_CTRL1_LINK_RATE_2160 5
#define DPLL_STATUS (0x6C060)
#define DPLL_LOCK(id) (1 << ((id) * 8))
#define LCPLL1_CTL (0x46010)
#define LCPLL2_CTL (0x46014)
#define LCPLL_PLL_ENABLE (1 << 31)
/* DPLL cfg */
#define _DPLL1_CFGCR1 0x6C040
#define _DPLL2_CFGCR1 0x6C048
#define _DPLL3_CFGCR1 0x6C050
#define DPLL_CFGCR1_FREQ_ENABLE (1 << 31)