forked from ps5-linux/ps5-linux-patches
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinux.patch
More file actions
7770 lines (7695 loc) · 300 KB
/
Copy pathlinux.patch
File metadata and controls
7770 lines (7695 loc) · 300 KB
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
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index fe106da41ae5..6fd78cbfe1d6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -605,6 +605,14 @@ config X86_NUMACHIP
enable more than ~168 cores.
If you don't have one of these, you should say N here.
+config X86_PS5
+ bool "Sony PlayStation 5"
+ depends on X86_64
+ depends on X86_EXTENDED_PLATFORM
+ depends on PCI
+ help
+ Select to include support for the Sony PlayStation 5 game console.
+
config X86_VSMP
bool "ScaleMP vSMP"
select HYPERVISOR_GUEST
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 4efbbf9d117b..403d5ff74ef0 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -26,6 +26,7 @@
#define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */
#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */
#define _EFER_TCE 15 /* Enable Translation Cache Extensions */
+#define _EFER_NDA 16 /* No data access enable */
#define _EFER_AUTOIBRS 21 /* Enable Automatic IBRS */
#define EFER_SCE (1<<_EFER_SCE)
@@ -36,6 +37,7 @@
#define EFER_LMSLE (1<<_EFER_LMSLE)
#define EFER_FFXSR (1<<_EFER_FFXSR)
#define EFER_TCE (1<<_EFER_TCE)
+#define EFER_NDA (1<<_EFER_NDA)
#define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS)
/*
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 2ec250ba467e..f4654b2e63d0 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -21,8 +21,9 @@
#define _PAGE_BIT_SOFTW2 10 /* " */
#define _PAGE_BIT_SOFTW3 11 /* " */
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
-#define _PAGE_BIT_SOFTW4 57 /* available for programmer */
-#define _PAGE_BIT_SOFTW5 58 /* available for programmer */
+#define _PAGE_BIT_SOFTW4 56 /* available for programmer */
+#define _PAGE_BIT_SOFTW5 57 /* available for programmer */
+#define _PAGE_BIT_NDA 58 /* No data access */
#define _PAGE_BIT_PKEY_BIT0 59 /* Protection Keys, bit 1/4 */
#define _PAGE_BIT_PKEY_BIT1 60 /* Protection Keys, bit 2/4 */
#define _PAGE_BIT_PKEY_BIT2 61 /* Protection Keys, bit 3/4 */
@@ -65,6 +66,7 @@
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
#define _PAGE_KERNEL_4K (_AT(pteval_t, 1) << _PAGE_BIT_KERNEL_4K)
+#define _PAGE_NDA (_AT(pteval_t, 1) << _PAGE_BIT_NDA)
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT0)
#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT1)
@@ -192,6 +194,7 @@ enum page_cache_mode {
#define ___D _PAGE_DIRTY
#define ___G _PAGE_GLOBAL
#define __NX _PAGE_NX
+#define _NDA _PAGE_NDA
#define _ENC _PAGE_ENC
#define __WP _PAGE_CACHE_WP
@@ -210,6 +213,7 @@ enum page_cache_mode {
#define PAGE_COPY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
#define PAGE_READONLY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
#define PAGE_READONLY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0)
+#define PAGE_EXECONLY __pg(__PP| 0|_USR|___A|_NDA| 0| 0| 0)
/*
* Page tables needs to have Write=1 in order for any lower PTEs to be
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 914eb32581c7..1199b0762d60 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -69,6 +69,12 @@ extern void x86_ce4100_early_setup(void);
static inline void x86_ce4100_early_setup(void) { }
#endif
+#ifdef CONFIG_X86_PS5
+extern void x86_ps5_early_setup(void);
+#else
+static inline void x86_ps5_early_setup(void) { }
+#endif
+
#include <linux/kexec_handover.h>
#ifndef _SETUP
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index dafbf581c515..791687363cbf 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -207,6 +207,7 @@ enum x86_hardware_subarch {
X86_SUBARCH_XEN,
X86_SUBARCH_INTEL_MID,
X86_SUBARCH_CE4100,
+ X86_SUBARCH_PS5,
X86_NR_SUBARCHS,
};
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index fd28b53dbac5..569fc764d267 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -303,6 +303,11 @@ void __init __noreturn x86_64_start_reservations(char *real_mode_data)
case X86_SUBARCH_INTEL_MID:
x86_intel_mid_early_setup();
break;
+#ifdef CONFIG_X86_PS5
+ case X86_SUBARCH_PS5:
+ x86_ps5_early_setup();
+ break;
+#endif
default:
break;
}
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index cb9852ad6098..83bb0cf9e40b 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -31,6 +31,11 @@ struct clock_event_device *global_clock_event;
*/
static bool __init use_pit(void)
{
+#ifdef CONFIG_X86_PS5
+ /* PIT is not available. */
+ return false;
+#endif
+
if (!IS_ENABLED(CONFIG_X86_TSC) || !boot_cpu_has(X86_FEATURE_TSC))
return true;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ccc7b2e34a11..7d941c4d30f6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -112,7 +112,11 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_host);
*/
#ifdef CONFIG_X86_64
static
+#ifdef CONFIG_X86_PS5
+u64 __read_mostly efer_reserved_bits = ~((u64)(EFER_SCE | EFER_LME | EFER_LMA | EFER_NDA));
+#else
u64 __read_mostly efer_reserved_bits = ~((u64)(EFER_SCE | EFER_LME | EFER_LMA));
+#endif
#else
static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
#endif
diff --git a/arch/x86/mm/pgprot.c b/arch/x86/mm/pgprot.c
index dc1afd5c839d..745db92fb2c1 100644
--- a/arch/x86/mm/pgprot.c
+++ b/arch/x86/mm/pgprot.c
@@ -10,7 +10,11 @@ static pgprot_t protection_map[16] __ro_after_init = {
[VM_READ] = PAGE_READONLY,
[VM_WRITE] = PAGE_COPY,
[VM_WRITE | VM_READ] = PAGE_COPY,
+#ifdef CONFIG_X86_PS5
+ [VM_EXEC] = PAGE_EXECONLY,
+#else
[VM_EXEC] = PAGE_READONLY_EXEC,
+#endif
[VM_EXEC | VM_READ] = PAGE_READONLY_EXEC,
[VM_EXEC | VM_WRITE] = PAGE_COPY_EXEC,
[VM_EXEC | VM_WRITE | VM_READ] = PAGE_COPY_EXEC,
@@ -18,7 +22,11 @@ static pgprot_t protection_map[16] __ro_after_init = {
[VM_SHARED | VM_READ] = PAGE_READONLY,
[VM_SHARED | VM_WRITE] = PAGE_SHARED,
[VM_SHARED | VM_WRITE | VM_READ] = PAGE_SHARED,
+#ifdef CONFIG_X86_PS5
+ [VM_SHARED | VM_EXEC] = PAGE_EXECONLY,
+#else
[VM_SHARED | VM_EXEC] = PAGE_READONLY_EXEC,
+#endif
[VM_SHARED | VM_EXEC | VM_READ] = PAGE_READONLY_EXEC,
[VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_SHARED_EXEC,
[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED_EXEC
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 63105b29fbf5..f38e2601531c 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -57,14 +57,100 @@ int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
return -EINVAL;
}
+#ifdef CONFIG_X86_PS5
+static DEFINE_RAW_SPINLOCK(pci_lock);
+
+static int sfc_read(unsigned int domain, unsigned int bus, unsigned int rid,
+ int reg, int len, u32 *val)
+{
+ int busno;
+ int slot;
+ int func;
+
+ busno = (rid >> 8) & 0xff;
+ slot = (rid & 0xff) >> 3;
+ func = rid & 0x07;
+
+ if (busno == 0 || busno == 32) {
+ raw_pci_write(domain, bus, 0, 0xd90, 4, 4);
+ raw_pci_write(domain, bus, 0, 0xd80, 4, (32 << 24) | (slot << 19) | (func << 16) | (reg & 0xf80));
+ return raw_pci_read(domain, bus, 0, (reg & 0x7f) | 0xf80, len, val);
+ } else if (busno < 32) {
+ raw_pci_write(domain, bus, 0, 0xd10, 4, busno == 1 ? 4 : 5);
+ raw_pci_write(domain, bus, 0, 0xd00, 4, (busno << 24) | (slot << 19) | (func << 16) | (reg & 0xf80));
+ return raw_pci_read(domain, bus, 0, (reg & 0x7f) | 0xf00, len, val);
+ } else {
+ panic("wrong bus number");
+ }
+}
+
+static int sfc_write(unsigned int domain, unsigned int bus, unsigned int rid,
+ int reg, int len, u32 val)
+{
+ int busno;
+ int slot;
+ int func;
+
+ busno = (rid >> 8) & 0xff;
+ slot = (rid & 0xff) >> 3;
+ func = rid & 0x07;
+
+ if (busno == 0 || busno == 32) {
+ raw_pci_write(domain, bus, 0, 0xd90, 4, 4);
+ raw_pci_write(domain, bus, 0, 0xd80, 4, (32 << 24) | (slot << 19) | (func << 16) | (reg & 0xf80));
+ return raw_pci_write(domain, bus, 0, (reg & 0x7f) | 0xf80, len, val);
+ } else if (busno < 32) {
+ raw_pci_write(domain, bus, 0, 0xd10, 4, busno == 1 ? 4 : 5);
+ raw_pci_write(domain, bus, 0, 0xd00, 4, (busno << 24) | (slot << 19) | (func << 16) | (reg & 0xf80));
+ return raw_pci_write(domain, bus, 0, (reg & 0x7f) | 0xf00, len, val);
+ } else {
+ panic("wrong bus number");
+ }
+}
+#endif
+
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
+ int ret;
+ unsigned long flags;
+
+#ifdef CONFIG_X86_PS5
+ if (pci_ari_enabled(bus)) {
+ u32 rid = 0;
+ raw_spin_lock_irqsave(&pci_lock, flags);
+ raw_pci_read(pci_domain_nr(bus), bus->number, devfn, 0x150, 2, &rid);
+ if (rid != 0 && rid != 0xffff) {
+ ret = sfc_read(pci_domain_nr(bus), bus->number, rid, where, size, value);
+ raw_spin_unlock_irqrestore(&pci_lock, flags);
+ return ret;
+ }
+ raw_spin_unlock_irqrestore(&pci_lock, flags);
+ }
+#endif
+
return raw_pci_read(pci_domain_nr(bus), bus->number,
devfn, where, size, value);
}
static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
+ int ret;
+ unsigned long flags;
+
+#ifdef CONFIG_X86_PS5
+ if (pci_ari_enabled(bus)) {
+ u32 rid = 0;
+ raw_spin_lock_irqsave(&pci_lock, flags);
+ raw_pci_read(pci_domain_nr(bus), bus->number, devfn, 0x150, 2, &rid);
+ if (rid != 0 && rid != 0xffff) {
+ ret = sfc_write(pci_domain_nr(bus), bus->number, rid, where, size, value);
+ raw_spin_unlock_irqrestore(&pci_lock, flags);
+ return ret;
+ }
+ raw_spin_unlock_irqrestore(&pci_lock, flags);
+ }
+#endif
+
return raw_pci_write(pci_domain_nr(bus), bus->number,
devfn, where, size, value);
}
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 0de436316a1d..dde625251c99 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1720,6 +1720,11 @@ static int pirq_enable_irq(struct pci_dev *dev)
{
u8 pin = 0;
+#ifdef CONFIG_X86_PS5
+ /* Legacy IRQ is not available. */
+ return 0;
+#endif
+
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (pin && !pcibios_lookup_irq(dev, 1)) {
char *msg = "";
@@ -1801,6 +1806,11 @@ bool mp_should_keep_irq(struct device *dev)
static void pirq_disable_irq(struct pci_dev *dev)
{
+#ifdef CONFIG_X86_PS5
+ /* Legacy IRQ is not available. */
+ return;
+#endif
+
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq);
diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
index 3ed03a2552d0..40ffa1a2156a 100644
--- a/arch/x86/platform/Makefile
+++ b/arch/x86/platform/Makefile
@@ -9,6 +9,7 @@ obj-y += intel/
obj-y += intel-mid/
obj-y += intel-quark/
obj-y += olpc/
+obj-y += ps5/
obj-y += scx200/
obj-y += ts5500/
obj-y += uv/
diff --git a/arch/x86/platform/ps5/Makefile b/arch/x86/platform/ps5/Makefile
new file mode 100644
index 000000000000..5263181876f8
--- /dev/null
+++ b/arch/x86/platform/ps5/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_X86_PS5) += ps5.o
diff --git a/arch/x86/platform/ps5/ps5.c b/arch/x86/platform/ps5/ps5.c
new file mode 100644
index 000000000000..731fed163a83
--- /dev/null
+++ b/arch/x86/platform/ps5/ps5.c
@@ -0,0 +1,51 @@
+#include <linux/module.h>
+#include <linux/ps5.h>
+
+#include <asm/apic.h>
+#include <asm/i8259.h>
+#include <asm/reboot.h>
+#include <asm/setup.h>
+
+#define PS5_DEFAULT_TSC_FREQ 1596300000
+
+static __noreturn void ps5_power_off(void) {
+ icc_power_shutdown();
+}
+
+static __noreturn void ps5_emergency_restart(void) {
+ icc_power_reboot();
+}
+
+static __noreturn void ps5_restart(char *cmd) {
+ ps5_emergency_restart();
+}
+
+static unsigned long __init ps5_calibrate_tsc(void)
+{
+ return PS5_DEFAULT_TSC_FREQ / 1000;
+}
+
+static void ps5_get_wallclock(struct timespec64 *now)
+{
+ now->tv_sec = now->tv_nsec = 0;
+}
+
+static int ps5_set_wallclock(const struct timespec64 *now)
+{
+ return -ENODEV;
+}
+
+void __init x86_ps5_early_setup(void)
+{
+ x86_platform.calibrate_tsc = ps5_calibrate_tsc;
+ x86_platform.get_wallclock = ps5_get_wallclock;
+ x86_platform.set_wallclock = ps5_set_wallclock;
+ x86_platform.legacy.rtc = 0;
+
+ machine_ops.restart = ps5_restart;
+ machine_ops.power_off = ps5_power_off;
+ machine_ops.emergency_restart = ps5_emergency_restart;
+ pm_power_off = ps5_power_off;
+
+ legacy_pic = &null_legacy_pic;
+}
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 75474fb3848e..44a0744533a0 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -90,6 +90,9 @@
#include "check.h"
#include "efi.h"
+#define PS5_M2_PART44_LBA_OFFSET 34224
+#define PS5_M2_MBR_LBA 65536
+
/* This allows a kernel command line option 'gpt' to override
* the test for invalid PMBR. Not __initdata because reloading
* the partition tables happens after init too.
@@ -133,6 +136,12 @@ efi_crc32(const void *buf, unsigned long len)
*/
static u64 last_lba(struct gendisk *disk)
{
+#ifdef CONFIG_X86_PS5
+ if (strncmp(disk->disk_name, "nvme", 4) == 0) {
+ return div_u64(bdev_nr_bytes(disk->part0),
+ queue_logical_block_size(disk->queue)) - 1ULL - PS5_M2_PART44_LBA_OFFSET;
+ } else
+#endif
return div_u64(bdev_nr_bytes(disk->part0),
queue_logical_block_size(disk->queue)) - 1ULL;
}
@@ -143,8 +152,14 @@ static inline int pmbr_part_valid(gpt_mbr_record *part)
goto invalid;
/* set to 0x00000001 (i.e., the LBA of the GPT Partition Header) */
+#ifdef CONFIG_X86_PS5
+ if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA &&
+ le32_to_cpu(part->starting_lba) != PS5_M2_MBR_LBA + GPT_PRIMARY_PARTITION_TABLE_LBA)
+ goto invalid;
+#else
if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA)
goto invalid;
+#endif
return GPT_MBR_PROTECTIVE;
invalid:
@@ -599,6 +614,11 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
if (!legacymbr)
goto fail;
+#ifdef CONFIG_X86_PS5
+ if (strncmp(state->disk->disk_name, "nvme", 4) == 0) {
+ read_lba(state, PS5_M2_MBR_LBA, (u8 *)legacymbr, sizeof(*legacymbr));
+ } else
+#endif
read_lba(state, 0, (u8 *)legacymbr, sizeof(*legacymbr));
good_pmbr = is_pmbr_valid(legacymbr, total_sectors);
kfree(legacymbr);
@@ -611,6 +631,12 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
"protective" : "hybrid");
}
+#ifdef CONFIG_X86_PS5
+ if (strncmp(state->disk->disk_name, "nvme", 4) == 0) {
+ good_pgpt = is_gpt_valid(state, PS5_M2_MBR_LBA + GPT_PRIMARY_PARTITION_TABLE_LBA,
+ &pgpt, &pptes);
+ } else
+#endif
good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
&pgpt, &pptes);
if (good_pgpt)
diff --git a/drivers/Makefile b/drivers/Makefile
index 53fbd2e0acdd..d36c1909e0e6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -199,3 +199,5 @@ obj-y += resctrl/
obj-$(CONFIG_DIBS) += dibs/
obj-$(CONFIG_S390) += s390/
+
+obj-$(CONFIG_X86_PS5) += ps5/
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
index 477a37e2ef80..e1af70946c89 100644
--- a/drivers/firmware/dmi-id.c
+++ b/drivers/firmware/dmi-id.c
@@ -228,8 +228,16 @@ static int __init dmi_id_init(void)
{
int ret;
+#ifdef CONFIG_X86_PS5
+ dmi_set_system_info(DMI_SYS_VENDOR, "Sony Interactive Entertainment");
+ dmi_set_system_info(DMI_PRODUCT_NAME, "PlayStation 5");
+ /* Filled by spcie.c */
+ dmi_set_system_info(DMI_PRODUCT_VERSION, "Unknown");
+ dmi_set_system_info(DMI_PRODUCT_SERIAL, "Unknown");
+#else
if (!dmi_available)
return -ENODEV;
+#endif
dmi_id_init_attr_table();
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 70d39adf50dc..5d283649817e 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -953,6 +953,14 @@ const char *dmi_get_system_info(int field)
}
EXPORT_SYMBOL(dmi_get_system_info);
+#ifdef CONFIG_X86_PS5
+void dmi_set_system_info(int field, const char *str)
+{
+ dmi_ident[field] = str;
+}
+EXPORT_SYMBOL(dmi_set_system_info);
+#endif
+
/**
* dmi_name_in_serial - Check if string is in the DMI product serial information
* @str: string to check for
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 447e734c362b..c52c81e084a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -271,6 +271,10 @@ extern int amdgpu_user_queue;
extern uint amdgpu_hdmi_hpd_debounce_delay_ms;
+#ifdef CONFIG_X86_PS5
+extern int amdgpu_force_1080p;
+#endif
+
#define AMDGPU_VM_MAX_NUM_CTX 4096
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 35d04e69aec0..314ceaaaab9f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -221,8 +221,14 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
{
+#ifdef CONFIG_X86_PS5
+ /* Hardcode vbios rom address. */
+ phys_addr_t rom = 0xc0000;
+ size_t romlen = 0x10000;
+#else
phys_addr_t rom = adev->pdev->rom;
size_t romlen = adev->pdev->romlen;
+#endif
void __iomem *bios;
adev->bios = NULL;
@@ -436,6 +442,7 @@ static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
{
+#ifndef CONFIG_X86_PS5
if (amdgpu_acpi_vfct_bios(adev)) {
dev_info(adev->dev, "Fetched VBIOS from VFCT\n");
goto success;
@@ -450,6 +457,7 @@ static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
dev_info(adev->dev, "Fetched VBIOS from ROM BAR\n");
goto success;
}
+#endif
if (amdgpu_read_platform_bios(adev)) {
dev_info(adev->dev, "Fetched VBIOS from platform\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 2ec69fa05cb1..502b878373e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2512,6 +2512,26 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
case CHIP_CYAN_SKILLFISH:
if (adev->discovery.bin)
return 0;
+#ifdef CONFIG_X86_PS5
+ /* Hardcode gfxinfo. */
+ adev->gfx.config.max_shader_engines = 2;
+ adev->gfx.config.max_cu_per_sh = 10;
+ adev->gfx.config.max_sh_per_se = 2;
+ adev->gfx.config.max_backends_per_se = 8;
+ adev->gfx.config.max_texture_channel_caches = 16;
+ adev->gfx.config.max_gprs = 1024;
+ adev->gfx.config.max_gs_threads = 32;
+ adev->gfx.config.gs_vgt_table_depth = 32;
+ adev->gfx.config.gs_prim_buffer_depth = 1792;
+ adev->gfx.config.double_offchip_lds_buf = 1;
+ adev->gfx.cu_info.wave_front_size = 32;
+ adev->gfx.cu_info.max_waves_per_simd = 20;
+ adev->gfx.cu_info.max_scratch_slots_per_cu = 32;
+ adev->gfx.cu_info.lds_size = 64;
+ adev->gfx.config.num_sc_per_sh = 1;
+ adev->gfx.config.num_packer_per_sc = 2;
+ return 0;
+#endif
chip_name = "cyan_skillfish";
break;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 3459d356151e..f09233c05e04 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -2914,6 +2914,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 8);
adev->ip_versions[GC_HWIP][0] = IP_VERSION(10, 1, 3);
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 0, 3);
+#ifdef CONFIG_X86_PS5
+ adev->ip_versions[DCE_HWIP][0] = IP_VERSION(2, 0, 3);
+#endif
}
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index c91638e65174..00618809031f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -41,6 +41,10 @@
#include <linux/suspend.h>
#include <linux/vga_switcheroo.h>
+#ifdef CONFIG_X86_PS5
+#include <linux/ps5.h>
+#endif
+
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
#include "amdgpu_dma_buf.h"
@@ -1134,6 +1138,12 @@ module_param_named(user_queue, amdgpu_user_queue, int, 0444);
MODULE_PARM_DESC(hdmi_hpd_debounce_delay_ms, "HDMI HPD disconnect debounce delay in milliseconds (0 to disable (by default), 1500 is common)");
module_param_named(hdmi_hpd_debounce_delay_ms, amdgpu_hdmi_hpd_debounce_delay_ms, uint, 0644);
+#ifdef CONFIG_X86_PS5
+int amdgpu_force_1080p = 0;
+MODULE_PARM_DESC(force_1080p, "Force 1080p (0 = disabled (default), 1 = enabled)");
+module_param_named(force_1080p, amdgpu_force_1080p, int, 0444);
+#endif
+
/* These devices are not supported by amdgpu.
* They are supported by the mach64, r128, radeon drivers
*/
@@ -2179,6 +2189,7 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x7410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
/* CYAN_SKILLFISH */
+ {0x1002, 0x13DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
{0x1002, 0x13DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
{0x1002, 0x13F9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
{0x1002, 0x13FA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
@@ -2393,6 +2404,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
int ret, retry = 0, i;
bool supports_atomic = false;
+#ifdef CONFIG_X86_PS5
+ if (!spcie_is_initialized())
+ return -EPROBE_DEFER;
+#endif
+
if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA ||
(pdev->class >> 8) == PCI_CLASS_DISPLAY_OTHER) {
if (drm_firmware_drivers_only() && amdgpu_modeset == -1)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 77578ecc6782..b037a6f57a6d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -2344,6 +2344,11 @@ void amdgpu_gfx_profile_ring_begin_use(struct amdgpu_ring *ring)
enum PP_SMC_POWER_PROFILE profile;
int r;
+#ifdef CONFIG_X86_PS5
+ /* DPM is not supported. */
+ return;
+#endif
+
if (amdgpu_dpm_is_overdrive_enabled(adev))
return;
@@ -2379,6 +2384,11 @@ void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
+#ifdef CONFIG_X86_PS5
+ /* DPM is not supported. */
+ return;
+#endif
+
if (amdgpu_dpm_is_overdrive_enabled(adev))
return;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index 321310ba2c08..764da52902ac 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -210,6 +210,9 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
const struct sdma_firmware_header_v3_0 *sdma_hv3;
uint16_t version_major;
char ucode_prefix[30];
+#ifdef CONFIG_X86_PS5
+ struct common_firmware_header *hdr;
+#endif
amdgpu_ucode_ip_version_decode(adev, SDMA0_HWIP, ucode_prefix, sizeof(ucode_prefix));
if (instance == 0)
@@ -222,6 +225,11 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
"amdgpu/%s%d.bin", ucode_prefix, instance);
if (err)
goto out;
+#ifdef CONFIG_X86_PS5
+ hdr = (struct common_firmware_header *)adev->sdma.instance[instance].fw->data;
+ hdr->ucode_array_offset_bytes = cpu_to_le32(le32_to_cpu(hdr->ucode_array_offset_bytes) + 0x100);
+ hdr->ucode_size_bytes = cpu_to_le32(le32_to_cpu(hdr->ucode_size_bytes) - 0x200);
+#endif
header = (const struct common_firmware_header *)
adev->sdma.instance[instance].fw->data;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 8b60299b73ef..db803401a3be 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -4202,6 +4202,14 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev)
}
}
+static void gfx_v10_0_patch_ucode(const u8 *data)
+{
+ struct common_firmware_header *hdr;
+ hdr = (struct common_firmware_header *)data;
+ hdr->ucode_array_offset_bytes = cpu_to_le32(le32_to_cpu(hdr->ucode_array_offset_bytes) + 0x100);
+ hdr->ucode_size_bytes = cpu_to_le32(le32_to_cpu(hdr->ucode_size_bytes) - 0x200);
+}
+
static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
{
char fw_name[53];
@@ -4224,6 +4232,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
"amdgpu/%s_pfp%s.bin", ucode_prefix, wks);
if (err)
goto out;
+#ifdef CONFIG_X86_PS5
+ gfx_v10_0_patch_ucode(adev->gfx.pfp_fw->data);
+#endif
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
err = amdgpu_ucode_request(adev, &adev->gfx.me_fw,
@@ -4231,6 +4242,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
"amdgpu/%s_me%s.bin", ucode_prefix, wks);
if (err)
goto out;
+#ifdef CONFIG_X86_PS5
+ gfx_v10_0_patch_ucode(adev->gfx.me_fw->data);
+#endif
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
err = amdgpu_ucode_request(adev, &adev->gfx.ce_fw,
@@ -4238,6 +4252,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
"amdgpu/%s_ce%s.bin", ucode_prefix, wks);
if (err)
goto out;
+#ifdef CONFIG_X86_PS5
+ gfx_v10_0_patch_ucode(adev->gfx.ce_fw->data);
+#endif
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE);
if (!amdgpu_sriov_vf(adev)) {
@@ -4245,6 +4262,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
if (err)
goto out;
+#ifdef CONFIG_X86_PS5
+ gfx_v10_0_patch_ucode(adev->gfx.rlc_fw->data);
+#endif
/* don't validate this firmware. There are apparently firmwares
* in the wild with incorrect size in the header
@@ -4262,6 +4282,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
"amdgpu/%s_mec%s.bin", ucode_prefix, wks);
if (err)
goto out;
+#ifdef CONFIG_X86_PS5
+ gfx_v10_0_patch_ucode(adev->gfx.mec_fw->data);
+#endif
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1);
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
@@ -4269,6 +4292,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
AMDGPU_UCODE_REQUIRED,
"amdgpu/%s_mec2%s.bin", ucode_prefix, wks);
if (!err) {
+#ifdef CONFIG_X86_PS5
+ gfx_v10_0_patch_ucode(adev->gfx.mec2_fw->data);
+#endif
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index f17c3839aea1..a561038f3f79 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -868,6 +868,10 @@ static int nv_common_early_init(struct amdgpu_ip_block *ip_block)
adev->cg_flags = 0;
adev->pg_flags = 0;
adev->external_rev_id = adev->rev_id + 0x82;
+#ifdef CONFIG_X86_PS5
+ /* Hardcode bc250's id. Remove when mesa's patch is widely available. */
+ adev->external_rev_id = 0x84;
+#endif
break;
case IP_VERSION(10, 3, 6):
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index e3a035c9fece..6eb67dd7b52c 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -1362,6 +1362,12 @@ static int sdma_v5_0_early_init(struct amdgpu_ip_block *ip_block)
struct amdgpu_device *adev = ip_block->adev;
int r;
+#ifdef CONFIG_X86_PS5
+ /* Reset SDMA to prevent ring test failures after reload. */
+ sdma_v5_0_soft_reset_engine(adev, 0);
+ sdma_v5_0_soft_reset_engine(adev, 1);
+#endif
+
r = sdma_v5_0_init_microcode(adev);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0aee65503642..1ca2bcd7755d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -80,6 +80,10 @@
#include <linux/component.h>
#include <linux/sort.h>
+#ifdef CONFIG_X86_PS5
+#include <linux/ps5.h>
+#endif
+
#include <drm/drm_privacy_screen_consumer.h>
#include <drm/display/drm_dp_mst_helper.h>
#include <drm/display/drm_hdmi_helper.h>
@@ -3007,7 +3011,10 @@ static int dm_hw_init(struct amdgpu_ip_block *ip_block)
r = amdgpu_dm_init(adev);
if (r)
return r;
+#ifndef CONFIG_X86_PS5
+ /* HPD is not supported. */
amdgpu_dm_hpd_init(adev);
+#endif
r = dm_oem_i2c_hw_init(adev);
if (r)
@@ -3028,7 +3035,10 @@ static int dm_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
+#ifndef CONFIG_X86_PS5
+ /* HPD is not supported. */
amdgpu_dm_hpd_fini(adev);
+#endif
amdgpu_dm_irq_fini(adev);
amdgpu_dm_fini(adev);
@@ -6809,6 +6819,12 @@ static void fill_stream_properties_from_drm_display_mode(
stream->output_color_space = get_output_color_space(timing_out, connector_state);
stream->content_type = get_output_content_type(connector_state);
+
+#ifdef CONFIG_X86_PS5
+ /* Hardcode RGB888. */
+ // timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+ // timing_out->display_color_depth = COLOR_DEPTH_888;
+#endif
}
static void fill_audio_info(struct audio_info *audio_info,
@@ -8198,6 +8214,11 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
*/
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+#ifdef CONFIG_X86_PS5
+ if (!isHdmiModeValid(mode, amdgpu_force_1080p))
+ return MODE_ERROR;
+#endif
+
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
(mode->flags & DRM_MODE_FLAG_DBLSCAN))
return result;
@@ -10458,6 +10479,9 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
new_crtc_state, i) {
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+#ifdef CONFIG_X86_PS5
+ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+#endif
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
if (old_crtc_state->active &&
@@ -10465,6 +10489,11 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
drm_atomic_crtc_needs_modeset(new_crtc_state))) {
manage_dm_interrupts(adev, acrtc, NULL);
dc_stream_release(dm_old_crtc_state->stream);
+#ifdef CONFIG_X86_PS5
+ if (dm_new_crtc_state->stream && dc_is_dp_signal(dm_new_crtc_state->stream->signal)) {
+ sceHdmiInitVideoConfig();
+ }
+#endif
}
}
@@ -11035,6 +11064,22 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
dc_stream_retain(dm_new_crtc_state->stream);
acrtc->dm_irq_params.stream = dm_new_crtc_state->stream;
manage_dm_interrupts(adev, acrtc, dm_new_crtc_state);
+#ifdef CONFIG_X86_PS5
+ if (dm_new_crtc_state->stream && dc_is_dp_signal(dm_new_crtc_state->stream->signal)) {
+ struct dc_stream_state *stream = dm_new_crtc_state->stream;
+ int channels = 0;
+
+ for (i = 0; i < stream->audio_info.mode_count; i++) {
+ if (stream->audio_info.modes[i].channel_count > channels)
+ channels = stream->audio_info.modes[i].channel_count;
+ }
+
+ sceHdmiSetVideoConfig(&new_crtc_state->mode);
+ sceHdmiDeviceSetVideoMute(0);
+ sceHdmiSetAudioConfig(channels);
+ sceHdmiSetAudioMute(0);
+ }
+#endif
}
/* Handle vrr on->off / off->on transitions */
amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 896f4719cf7b..0eb818421a50 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -204,6 +204,7 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
asic_id.chip_id == DEVICE_ID_NV_13FA ||
asic_id.chip_id == DEVICE_ID_NV_13FB ||
asic_id.chip_id == DEVICE_ID_NV_13FC ||
+ asic_id.chip_id == DEVICE_ID_NV_13DA ||
asic_id.chip_id == DEVICE_ID_NV_13DB) {
dc_version = DCN_VERSION_2_01;
break;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
index 9459e8f28338..063e4a4eefdd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
@@ -98,8 +98,11 @@ static const struct link_encoder_funcs dcn201_link_enc_funcs = {
.disable_hpd = dcn10_link_encoder_disable_hpd,
.is_dig_enabled = dcn10_is_dig_enabled,
.destroy = dcn10_link_encoder_destroy,
+#ifndef CONFIG_X86_PS5
+ /* Ignore this to prevent blackscreen. */
.fec_set_enable = enc2_fec_set_enable,
.fec_set_ready = enc2_fec_set_ready,
+#endif
.get_dig_frontend = dcn10_get_dig_frontend,
.fec_is_active = enc2_fec_is_active,
.is_in_alt_mode = dcn201_link_encoder_is_in_alt_mode,
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c
index 13e14aad3daa..edc4b9ccfea4 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c
@@ -986,6 +986,11 @@ void dcn10_link_encoder_enable_dp_output(
struct bp_transmitter_control cntl = { 0 };
enum bp_result result;
+#ifdef CONFIG_X86_PS5
+ /* Ignore this to prevent link training failure. */
+ return;
+#endif
+
/* Enable the PHY */
/* number_of_lanes is used for pixel clock adjust,
@@ -1065,6 +1070,11 @@ void dcn10_link_encoder_disable_output(
struct bp_transmitter_control cntl = { 0 };
enum bp_result result;
+#ifdef CONFIG_X86_PS5
+ /* Ignore this to prevent link training failure. */
+ return;
+#endif
+
if (enc->funcs->is_dig_enabled && !enc->funcs->is_dig_enabled(enc)) {
/* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
/*in DP_Alt_No_Connect case, we turn off the dig already,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 699a756bbc40..4a9d4ba6abf4 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -1753,6 +1753,11 @@ static void power_down_clock_sources(struct dc *dc)
{
int i;
+#ifdef CONFIG_X86_PS5
+ /* Ignore this to prevent blackscreen. */
+ return;
+#endif
+
if (dc->res_pool->dp_clock_source->funcs->cs_power_down(
dc->res_pool->dp_clock_source) == false)
dm_error("Failed to power down pll! (dp clk src)\n");
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index cdc7587cf0b6..7a7b17fe5a89 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c