summaryrefslogtreecommitdiffstats
path: root/meta-xilinx-core/dynamic-layers
diff options
context:
space:
mode:
Diffstat (limited to 'meta-xilinx-core/dynamic-layers')
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend16
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi16
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi12
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts13
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi43
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi12
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb3
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb38
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb4
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb16
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb4
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb16
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202210.2.13.479.bbappend (renamed from meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_%.bbappend)0
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend8
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend11
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend11
-rw-r--r--meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend8
-rw-r--r--meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch1058
-rw-r--r--meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch110
-rw-r--r--meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch141
-rw-r--r--meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend10
-rw-r--r--meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend6
22 files changed, 1457 insertions, 99 deletions
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend
index 7dcee565..7d374291 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend
@@ -3,19 +3,19 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
3# openamp.dtsi is in the WORKDIR 3# openamp.dtsi is in the WORKDIR
4DT_INCLUDE:append = " ${WORKDIR}" 4DT_INCLUDE:append = " ${WORKDIR}"
5 5
6do_configure[vardeps] += "ENABLE_OPENAMP_DTSI OPENAMP_EXTRA_OVERLAYS" 6do_configure[vardeps] += "ENABLE_OPENAMP_DTSI OPENAMP_EXTRA_DT_INCLUDE_FILES"
7 7
8OPENAMP_EXTRA_OVERLAYS:zynq = "zynq-openamp.dtsi" 8OPENAMP_EXTRA_DT_INCLUDE_FILES ?= ""
9OPENAMP_EXTRA_OVERLAYS:zynqmp = "zynqmp-openamp.dtsi" 9OPENAMP_EXTRA_DT_INCLUDE_FILES:zynqmp = "zynqmp-openamp.dtsi"
10OPENAMP_EXTRA_OVERLAYS:versal = "versal-openamp.dtsi" 10OPENAMP_EXTRA_DT_INCLUDE_FILES:versal = "versal-openamp.dtsi"
11OPENAMP_EXTRA_OVERLAYS:versal-net = "versal-net-openamp.dtsi" 11OPENAMP_EXTRA_DT_INCLUDE_FILES:versal-net = "versal-net-openamp.dtsi"
12 12
13def set_openamp_extra_overlays(d): 13def set_openamp_extra_dt_include_files(d):
14 distro_features = d.getVar('DISTRO_FEATURES', True) 14 distro_features = d.getVar('DISTRO_FEATURES', True)
15 enable_openamp_dtsi = d.getVar('ENABLE_OPENAMP_DTSI') 15 enable_openamp_dtsi = d.getVar('ENABLE_OPENAMP_DTSI')
16 if 'openamp' in distro_features and enable_openamp_dtsi == '1': 16 if 'openamp' in distro_features and enable_openamp_dtsi == '1':
17 return ' ${OPENAMP_EXTRA_OVERLAYS}' 17 return ' ${OPENAMP_EXTRA_DT_INCLUDE_FILES}'
18 else: 18 else:
19 return '' 19 return ''
20 20
21EXTRA_OVERLAYS:append = "${@set_openamp_extra_overlays(d)}" 21EXTRA_DT_INCLUDE_FILES:append = "${@set_openamp_extra_dt_include_files(d)}"
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi
index a918faf2..a1c939eb 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi
@@ -53,7 +53,7 @@
53 reg = <0x0 0xeba00000 0x0 0x10000>; 53 reg = <0x0 0xeba00000 0x0 0x10000>;
54 status = "okay"; 54 status = "okay";
55 compatible = "mmio-sram"; 55 compatible = "mmio-sram";
56 power-domain = <&versal_net_firmware 0x183180cb>; 56 power-domains = <&versal_net_firmware 0x183180cb>;
57 }; 57 };
58 58
59 tcm_0b: tcm_0b@eba10000 { 59 tcm_0b: tcm_0b@eba10000 {
@@ -61,7 +61,7 @@
61 reg = <0x0 0xeba10000 0x0 0x8000>; 61 reg = <0x0 0xeba10000 0x0 0x8000>;
62 status = "okay"; 62 status = "okay";
63 compatible = "mmio-sram"; 63 compatible = "mmio-sram";
64 power-domain = <&versal_net_firmware 0x183180cc>; 64 power-domains = <&versal_net_firmware 0x183180cc>;
65 }; 65 };
66 66
67 tcm_0c: tcm_0b@eba20000 { 67 tcm_0c: tcm_0b@eba20000 {
@@ -69,7 +69,7 @@
69 reg = <0x0 0xeba20000 0x0 0x8000>; 69 reg = <0x0 0xeba20000 0x0 0x8000>;
70 status = "okay"; 70 status = "okay";
71 compatible = "mmio-sram"; 71 compatible = "mmio-sram";
72 power-domain = <&versal_net_firmware 0x183180cd>; 72 power-domains = <&versal_net_firmware 0x183180cd>;
73 }; 73 };
74 74
75 tcm_1a: tcm_0a@eba40000 { 75 tcm_1a: tcm_0a@eba40000 {
@@ -77,7 +77,7 @@
77 reg = <0x0 0xeba40000 0x0 0x10000>; 77 reg = <0x0 0xeba40000 0x0 0x10000>;
78 status = "okay"; 78 status = "okay";
79 compatible = "mmio-sram"; 79 compatible = "mmio-sram";
80 power-domain = <&versal_net_firmware 0x183180ce>; 80 power-domains = <&versal_net_firmware 0x183180ce>;
81 }; 81 };
82 82
83 tcm_1b: tcm_0b@eba50000 { 83 tcm_1b: tcm_0b@eba50000 {
@@ -85,7 +85,7 @@
85 reg = <0x0 0xeba50000 0x0 0x8000>; 85 reg = <0x0 0xeba50000 0x0 0x8000>;
86 status = "okay"; 86 status = "okay";
87 compatible = "mmio-sram"; 87 compatible = "mmio-sram";
88 power-domain = <&versal_net_firmware 0x183180cf>; 88 power-domains = <&versal_net_firmware 0x183180cf>;
89 }; 89 };
90 90
91 tcm_1c: tcm_0b@eba60000 { 91 tcm_1c: tcm_0b@eba60000 {
@@ -93,7 +93,7 @@
93 reg = <0x0 0xeba60000 0x0 0x8000>; 93 reg = <0x0 0xeba60000 0x0 0x8000>;
94 status = "okay"; 94 status = "okay";
95 compatible = "mmio-sram"; 95 compatible = "mmio-sram";
96 power-domain = <&versal_net_firmware 0x183180d0>; 96 power-domains = <&versal_net_firmware 0x183180d0>;
97 }; 97 };
98 98
99 r52ss { 99 r52ss {
@@ -110,7 +110,7 @@
110 ranges; 110 ranges;
111 sram = <&tcm_0a>, <&tcm_0b>, <&tcm_0c>; 111 sram = <&tcm_0a>, <&tcm_0b>, <&tcm_0c>;
112 memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; 112 memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
113 power-domain = <&versal_net_firmware 0x181100BF>; 113 power-domains = <&versal_net_firmware 0x181100BF>;
114 mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; 114 mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
115 mbox-names = "tx", "rx"; 115 mbox-names = "tx", "rx";
116 }; 116 };
@@ -121,7 +121,7 @@
121 ranges; 121 ranges;
122 sram = <&tcm_1a>, <&tcm_1b>, <&tcm_1c>; 122 sram = <&tcm_1a>, <&tcm_1b>, <&tcm_1c>;
123 memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; 123 memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
124 power-domain = <&versal_net_firmware 0x181100C0>; 124 power-domains = <&versal_net_firmware 0x181100C0>;
125 mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; 125 mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
126 mbox-names = "tx", "rx"; 126 mbox-names = "tx", "rx";
127 }; 127 };
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi
index 01e337c7..b21b4096 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi
@@ -52,7 +52,7 @@
52 reg = <0x0 0xffe00000 0x0 0x10000>; 52 reg = <0x0 0xffe00000 0x0 0x10000>;
53 status = "okay"; 53 status = "okay";
54 compatible = "mmio-sram"; 54 compatible = "mmio-sram";
55 power-domain = <&versal_firmware 0x1831800b>; 55 power-domains = <&versal_firmware 0x1831800b>;
56 }; 56 };
57 57
58 tcm_0b: tcm_0b@ffe20000 { 58 tcm_0b: tcm_0b@ffe20000 {
@@ -60,7 +60,7 @@
60 reg = <0x0 0xffe20000 0x0 0x10000>; 60 reg = <0x0 0xffe20000 0x0 0x10000>;
61 status = "okay"; 61 status = "okay";
62 compatible = "mmio-sram"; 62 compatible = "mmio-sram";
63 power-domain = <&versal_firmware 0x1831800c>; 63 power-domains = <&versal_firmware 0x1831800c>;
64 }; 64 };
65 65
66 tcm_1a: tcm_1a@ffe90000 { 66 tcm_1a: tcm_1a@ffe90000 {
@@ -68,7 +68,7 @@
68 reg = <0x0 0xffe90000 0x0 0x10000>; 68 reg = <0x0 0xffe90000 0x0 0x10000>;
69 status = "okay"; 69 status = "okay";
70 compatible = "mmio-sram"; 70 compatible = "mmio-sram";
71 power-domain = <&versal_firmware 0x1831800d>; 71 power-domains = <&versal_firmware 0x1831800d>;
72 }; 72 };
73 73
74 tcm_1b: tcm_1b@ffeb0000 { 74 tcm_1b: tcm_1b@ffeb0000 {
@@ -76,7 +76,7 @@
76 reg = <0x0 0xffeb0000 0x0 0x10000>; 76 reg = <0x0 0xffeb0000 0x0 0x10000>;
77 status = "okay"; 77 status = "okay";
78 compatible = "mmio-sram"; 78 compatible = "mmio-sram";
79 power-domain = <&versal_firmware 0x1831800e>; 79 power-domains = <&versal_firmware 0x1831800e>;
80 }; 80 };
81 81
82 rf5ss@ff9a0000 { 82 rf5ss@ff9a0000 {
@@ -94,7 +94,7 @@
94 ranges; 94 ranges;
95 sram = <&tcm_0a>, <&tcm_0b>; 95 sram = <&tcm_0a>, <&tcm_0b>;
96 memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; 96 memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
97 power-domain = <&versal_firmware 0x18110005>; 97 power-domains = <&versal_firmware 0x18110005>;
98 mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; 98 mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
99 mbox-names = "tx", "rx"; 99 mbox-names = "tx", "rx";
100 }; 100 };
@@ -105,7 +105,7 @@
105 ranges; 105 ranges;
106 sram = <&tcm_1a>, <&tcm_1b>; 106 sram = <&tcm_1a>, <&tcm_1b>;
107 memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; 107 memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
108 power-domain = <&versal_firmware 0x18110006>; 108 power-domains = <&versal_firmware 0x18110006>;
109 mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; 109 mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
110 mbox-names = "tx", "rx"; 110 mbox-names = "tx", "rx";
111 }; 111 };
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts
deleted file mode 100644
index b5d238ff..00000000
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts
+++ /dev/null
@@ -1,13 +0,0 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * dts overlay file for Zynq OpenAMP
5 *
6 * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
7 *
8 */
9
10/dts-v1/;
11/plugin/;
12
13#include "zynq-openamp.dtsi"
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi
deleted file mode 100644
index 0e822202..00000000
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * dts file for Zynq OpenAMP
5 *
6 * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
7 *
8 */
9
10&{/} {
11 reserved-memory {
12 #address-cells = <1>;
13 #size-cells = <1>;
14 ranges;
15 vdev0vring0: vdev0vring0@3e800000 {
16 no-map;
17 compatible = "shared-dma-pool";
18 reg = <0x3e800000 0x4000>;
19 };
20 vdev0vring1: vdev0vring1@3e804000 {
21 no-map;
22 compatible = "shared-dma-pool";
23 reg = <0x3e804000 0x4000>;
24 };
25 vdev0buffer: vdev0buffer@3e808000 {
26 no-map;
27 compatible = "shared-dma-pool";
28 reg = <0x3e808000 0x100000>;
29 };
30 rproc_0_reserved: rproc@3e000000 {
31 no-map;
32 compatible = "shared-dma-pool";
33 reg = <0x3e000000 0x800000>;
34 };
35 };
36
37 remoteproc0: remoteproc@0 {
38 compatible = "xlnx,zynq_remoteproc";
39 firmware = "firmware";
40 memory-region = <&rproc_0_reserved>, <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>;
41 interrupt-parent = <&intc>;
42 };
43};
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi
index 8ef72656..1ad51fef 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi
@@ -52,7 +52,7 @@
52 reg = <0x0 0xffe00000 0x0 0x10000>; 52 reg = <0x0 0xffe00000 0x0 0x10000>;
53 status = "okay"; 53 status = "okay";
54 compatible = "mmio-sram"; 54 compatible = "mmio-sram";
55 power-domain = <&zynqmp_firmware 15>; 55 power-domains = <&zynqmp_firmware 15>;
56 }; 56 };
57 57
58 tcm_0b: tcm_0b@ffe20000 { 58 tcm_0b: tcm_0b@ffe20000 {
@@ -60,14 +60,14 @@
60 reg = <0x0 0xffe20000 0x0 0x10000>; 60 reg = <0x0 0xffe20000 0x0 0x10000>;
61 status = "okay"; 61 status = "okay";
62 compatible = "mmio-sram"; 62 compatible = "mmio-sram";
63 power-domain = <&zynqmp_firmware 16>; 63 power-domains = <&zynqmp_firmware 16>;
64 }; 64 };
65 tcm_1a: tcm_0a@ffe90000 { 65 tcm_1a: tcm_0a@ffe90000 {
66 no-map; 66 no-map;
67 reg = <0x0 0xffe90000 0x0 0x10000>; 67 reg = <0x0 0xffe90000 0x0 0x10000>;
68 status = "okay"; 68 status = "okay";
69 compatible = "mmio-sram"; 69 compatible = "mmio-sram";
70 power-domain = <&zynqmp_firmware 17>; 70 power-domains = <&zynqmp_firmware 17>;
71 }; 71 };
72 72
73 tcm_1b: tcm_0b@ffeb0000 { 73 tcm_1b: tcm_0b@ffeb0000 {
@@ -75,7 +75,7 @@
75 reg = <0x0 0xffeb0000 0x0 0x10000>; 75 reg = <0x0 0xffeb0000 0x0 0x10000>;
76 status = "okay"; 76 status = "okay";
77 compatible = "mmio-sram"; 77 compatible = "mmio-sram";
78 power-domain = <&zynqmp_firmware 18>; 78 power-domains = <&zynqmp_firmware 18>;
79 }; 79 };
80 rf5ss@ff9a0000 { 80 rf5ss@ff9a0000 {
81 compatible = "xlnx,zynqmp-r5-remoteproc"; 81 compatible = "xlnx,zynqmp-r5-remoteproc";
@@ -92,7 +92,7 @@
92 ranges; 92 ranges;
93 sram = <&tcm_0a>, <&tcm_0b>; 93 sram = <&tcm_0a>, <&tcm_0b>;
94 memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; 94 memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
95 power-domain = <&zynqmp_firmware 7>; 95 power-domains = <&zynqmp_firmware 7>;
96 mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; 96 mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
97 mbox-names = "tx", "rx"; 97 mbox-names = "tx", "rx";
98 }; 98 };
@@ -103,7 +103,7 @@
103 ranges; 103 ranges;
104 sram = <&tcm_1a>, <&tcm_1b>; 104 sram = <&tcm_1a>, <&tcm_1b>;
105 memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; 105 memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
106 power-domain = <&zynqmp_firmware 8>; 106 power-domains = <&zynqmp_firmware 8>;
107 mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; 107 mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
108 mbox-names = "tx", "rx"; 108 mbox-names = "tx", "rx";
109 }; 109 };
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb
index 9f481fec..7b626ee3 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb
@@ -5,8 +5,6 @@ LICENSE = "MIT"
5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" 5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
6 6
7SRC_URI = " \ 7SRC_URI = " \
8 file://zynq-openamp.dtsi \
9 file://zynq-openamp-overlay.dts \
10 file://zynqmp-openamp.dtsi \ 8 file://zynqmp-openamp.dtsi \
11 file://zynqmp-openamp-overlay.dts \ 9 file://zynqmp-openamp-overlay.dts \
12 file://versal-openamp.dtsi \ 10 file://versal-openamp.dtsi \
@@ -18,7 +16,6 @@ SRC_URI = " \
18# We don't have anything to include from the kernel 16# We don't have anything to include from the kernel
19KERNEL_INCLUDE = "" 17KERNEL_INCLUDE = ""
20 18
21COMPATIBLE_MACHINE:zynq = "${MACHINE}"
22COMPATIBLE_MACHINE:zynqmp = "${MACHINE}" 19COMPATIBLE_MACHINE:zynqmp = "${MACHINE}"
23COMPATIBLE_MACHINE:versal = "${MACHINE}" 20COMPATIBLE_MACHINE:versal = "${MACHINE}"
24COMPATIBLE_MACHINE:versal-net = "${MACHINE}" 21COMPATIBLE_MACHINE:versal-net = "${MACHINE}"
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb
new file mode 100644
index 00000000..13992ebc
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb
@@ -0,0 +1,38 @@
1DESCRIPTION = "OpenAMP supported packages"
2
3PACKAGE_ARCH = "${MACHINE_ARCH}"
4
5# We don't support Zynq
6COMPATIBLE_MACHINE:zynq = "$^"
7
8inherit packagegroup features_check
9
10REQUIRED_DISTRO_FEATURES = "openamp"
11
12PACKAGES = "\
13 packagegroup-openamp-echo-test \
14 packagegroup-openamp-matrix-mul \
15 packagegroup-openamp-rpc-demo \
16 packagegroup-openamp \
17 "
18
19RDEPENDS:${PN}-echo-test = "rpmsg-echo-test"
20RDEPENDS:${PN}-echo-test:append:zcu102-zynqmp = " openamp-fw-echo-testd"
21
22RDEPENDS:${PN}-matrix-mul = "rpmsg-mat-mul"
23RDEPENDS:${PN}-matrix-mul:append:zcu102-zynqmp = " openamp-fw-mat-muld"
24
25RDEPENDS:${PN}-rpc-demo = "rpmsg-proxy-app"
26RDEPENDS:${PN}-rpc-demo:append:zcu102-zynqmp = " openamp-fw-rpc-demo"
27
28RDEPENDS:${PN}:append = " ${@'open-amp-device-tree' if d.getVar('ENABLE_OPENAMP_DTSI') != '1' else ''}"
29
30RDEPENDS:${PN}:append = " \
31 libmetal \
32 libmetal-demos \
33 open-amp \
34 open-amp-demos \
35 packagegroup-openamp-echo-test \
36 packagegroup-openamp-matrix-mul \
37 packagegroup-openamp-rpc-demo \
38 "
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb
index a03912d7..9ca9cbc1 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb
@@ -1,8 +1,8 @@
1SRCBRANCH ?= "2024" 1SRCBRANCH ?= "2024"
2SRCREV = "e2fdb4fecbebe41b4cd1c0b4fbfa3496bcded485" 2SRCREV = "9e9997221ddd335c31cf881edf7026c762024a58"
3BRANCH = "xlnx_rel_v2024.1" 3BRANCH = "xlnx_rel_v2024.1"
4LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=f4d5df0f12dcea1b1a0124219c0dbab4" 4LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=f4d5df0f12dcea1b1a0124219c0dbab4"
5PV = "${SRCBRANCH}+git" 5PV .= "+git"
6 6
7REPO = "git://github.com/Xilinx/libmetal.git;protocol=https" 7REPO = "git://github.com/Xilinx/libmetal.git;protocol=https"
8 8
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb
new file mode 100644
index 00000000..bcde904d
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb
@@ -0,0 +1,16 @@
1SRCBRANCH ?= "2024"
2SRCREV = "e2fdb4fecbebe41b4cd1c0b4fbfa3496bcded485"
3BRANCH = "xlnx_rel_v2024.2"
4LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=f4d5df0f12dcea1b1a0124219c0dbab4"
5PV .= "+git"
6
7REPO = "git://github.com/Xilinx/libmetal.git;protocol=https"
8
9include ${LAYER_PATH_openamp-layer}/recipes-openamp/libmetal/libmetal.inc
10include ${LAYER_PATH_openamp-layer}/vendor/xilinx/recipes-openamp/libmetal/libmetal-xlnx.inc
11
12RPROVIDES:${PN}-dbg += "libmetal-dbg"
13RPROVIDES:${PN}-dev += "libmetal-dev"
14RPROVIDES:${PN}-lic += "libmetal-lic"
15RPROVIDES:${PN}-src += "libmetal-src"
16RPROVIDES:${PN}-staticdev += "libmetal-staticdev"
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb
index 94535abc..29d4bc4f 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb
@@ -1,8 +1,8 @@
1SRCBRANCH ?= "2024" 1SRCBRANCH ?= "2024"
2SRCREV = "dbf0857389190f4c4cedfb77bd1f9bdd7ab404f3" 2SRCREV = "699ad2c5b9236d61aae1b89e2857361db1bfeb95"
3BRANCH = "xlnx_rel_v2024.1" 3BRANCH = "xlnx_rel_v2024.1"
4LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=ab88daf995c0bd0071c2e1e55f3d3505" 4LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=ab88daf995c0bd0071c2e1e55f3d3505"
5PV = "${SRCBRANCH}+git" 5PV .= "+git"
6REPO = "git://github.com/Xilinx/open-amp.git;protocol=https" 6REPO = "git://github.com/Xilinx/open-amp.git;protocol=https"
7 7
8include ${LAYER_PATH_openamp-layer}/recipes-openamp/open-amp/open-amp.inc 8include ${LAYER_PATH_openamp-layer}/recipes-openamp/open-amp/open-amp.inc
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb
new file mode 100644
index 00000000..06c2ecbc
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb
@@ -0,0 +1,16 @@
1SRCBRANCH ?= "2024"
2SRCREV = "47caef116ccbf5d5a9778082a98fe8f3710b549c"
3BRANCH = "xlnx_rel_v2024.2"
4LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=ab88daf995c0bd0071c2e1e55f3d3505"
5PV .= "+git"
6REPO = "git://github.com/Xilinx/open-amp.git;protocol=https"
7
8include ${LAYER_PATH_openamp-layer}/recipes-openamp/open-amp/open-amp.inc
9require ${LAYER_PATH_openamp-layer}/vendor/xilinx/recipes-openamp/open-amp/open-amp-xlnx.inc
10
11RPROVIDES:${PN}-dbg += "open-amp-dbg"
12RPROVIDES:${PN}-dev += "open-amp-dev"
13RPROVIDES:${PN}-lic += "open-amp-lic"
14RPROVIDES:${PN}-src += "open-amp-src"
15RPROVIDES:${PN}-staticdev += "open-amp-staticdev"
16
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_%.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202210.2.13.479.bbappend
index 0e7f3693..0e7f3693 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_%.bbappend
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202210.2.13.479.bbappend
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend
new file mode 100644
index 00000000..0e7f3693
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend
@@ -0,0 +1,8 @@
1# Use libmetal for systems with AIE
2# For versal devices with the ai-engine
3PACKAGE_ARCH_orig := "${PACKAGE_ARCH}"
4PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}"
5EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}"
6TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}"
7DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}"
8RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}"
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend
index 362dc45a..a7ab6bb8 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend
@@ -1,2 +1,9 @@
1# Older xrt requires a manual dependency on libmetal 1# Use libmetal for systems with AIE
2DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libmetal', '', d)}" 2# For versal devices with the ai-engine
3PACKAGE_ARCH_orig := "${PACKAGE_ARCH}"
4PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}"
5EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}"
6TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}"
7DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal libmetal', '', d)}"
8RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}"
9
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend
index 362dc45a..a7ab6bb8 100644
--- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend
@@ -1,2 +1,9 @@
1# Older xrt requires a manual dependency on libmetal 1# Use libmetal for systems with AIE
2DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libmetal', '', d)}" 2# For versal devices with the ai-engine
3PACKAGE_ARCH_orig := "${PACKAGE_ARCH}"
4PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}"
5EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}"
6TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}"
7DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal libmetal', '', d)}"
8RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}"
9
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend
new file mode 100644
index 00000000..0e7f3693
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend
@@ -0,0 +1,8 @@
1# Use libmetal for systems with AIE
2# For versal devices with the ai-engine
3PACKAGE_ARCH_orig := "${PACKAGE_ARCH}"
4PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}"
5EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}"
6TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}"
7DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}"
8RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}"
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch
new file mode 100644
index 00000000..3fa4d6ec
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch
@@ -0,0 +1,1058 @@
1From 015f8a54f7e5a754e1cefba1aa7b1f6992a8aa9b Mon Sep 17 00:00:00 2001
2From: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
3Date: Tue, 16 Jul 2024 19:48:47 +0000
4Subject: [PATCH] xf86-video-armosc: Accelerate picture composition
5
6Introduce Repulsion - simplistic GPU accelerated compositor to back RandR
7display manipulation features. This library is inspired by Glamor extension
8https://www.freedesktop.org/wiki/Software/Glamor/. Unfortunately Glamor
9doesn't work as is on ARM Mali-400 MP due to the lack of required features
10and several bugs in Mali EGL/GLES implementation.
11
12Install and manage picture compositor hooks.
13
14Provide access to dma-buf fd from ARSOC buffer object.
15
16Attach shadow buffer object to corresponding pixmap.
17
18Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
19---
20 src/Makefile.am | 3 +-
21 src/armsoc_driver.c | 145 ++++++++++
22 src/armsoc_driver.h | 7 +
23 src/armsoc_dumb.c | 8 +
24 src/armsoc_dumb.h | 1 +
25 src/armsoc_exa.c | 18 +-
26 src/armsoc_repulsion.c | 624 +++++++++++++++++++++++++++++++++++++++++
27 src/armsoc_repulsion.h | 67 +++++
28 8 files changed, 867 insertions(+), 6 deletions(-)
29 create mode 100644 src/armsoc_repulsion.c
30 create mode 100644 src/armsoc_repulsion.h
31
32diff --git a/src/Makefile.am b/src/Makefile.am
33index db5f110..cd4f795 100644
34--- a/src/Makefile.am
35+++ b/src/Makefile.am
36@@ -38,7 +38,7 @@ ERROR_CFLAGS = -Werror -Wall -Wdeclaration-after-statement -Wvla \
37 AM_CFLAGS = @XORG_CFLAGS@ $(ERROR_CFLAGS)
38 armsoc_drv_la_LTLIBRARIES = armsoc_drv.la
39 armsoc_drv_la_LDFLAGS = -module -avoid-version -no-undefined
40-armsoc_drv_la_LIBADD = @XORG_LIBS@
41+armsoc_drv_la_LIBADD = -lMali @XORG_LIBS@
42 armsoc_drv_ladir = @moduledir@/drivers
43 DRMMODE_SRCS = drmmode_exynos/drmmode_exynos.c \
44 drmmode_pl111/drmmode_pl111.c \
45@@ -54,4 +54,5 @@ armsoc_drv_la_SOURCES = \
46 armsoc_dri2.c \
47 armsoc_driver.c \
48 armsoc_dumb.c \
49+ armsoc_repulsion.c \
50 $(DRMMODE_SRCS)
51diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
52index a4a1ba3..f5b8f21 100644
53--- a/src/armsoc_driver.c
54+++ b/src/armsoc_driver.c
55@@ -42,6 +42,7 @@
56 #include <pixman.h>
57
58 #include "armsoc_driver.h"
59+#include "armsoc_repulsion.h"
60
61 #include "micmap.h"
62
63@@ -971,6 +972,138 @@ ARMSOCAccelInit(ScreenPtr pScreen)
64 pARMSOC->dri = FALSE;
65 }
66
67+#define ARMSOC_ACCEL_MIN_DIMS 200
68+
69+/**
70+ * Classify compositor input to figure out if we can accelerate composition
71+ */
72+static Bool
73+ARMSOCCanAccelerateComposition(CARD8 op,
74+ PicturePtr src,
75+ PicturePtr mask,
76+ PicturePtr dest,
77+ CARD16 width,
78+ CARD16 height)
79+{
80+ /* We only support source to destination pixmap copy */
81+ if (op != PictOpSrc)
82+ return FALSE;
83+
84+ /*
85+ * Don't accelerate small picture compositions, e.g. toolbars, cursor,
86+ * icons, etc.
87+ */
88+ if (width < ARMSOC_ACCEL_MIN_DIMS || height < ARMSOC_ACCEL_MIN_DIMS)
89+ return FALSE;
90+
91+ /* Check source picture */
92+ if (!src || !src->pDrawable)
93+ return FALSE;
94+
95+ /* Check destination picture constraints */
96+ if (!dest || !dest->pDrawable || dest->pDrawable->type != DRAWABLE_PIXMAP)
97+ return FALSE;
98+
99+ /* We don't support masking */
100+ if (mask)
101+ return FALSE;
102+
103+ /*
104+ * We expect source transform to be assigned, otherwise there is not much
105+ * to accelerate
106+ */
107+ if (!src->transform)
108+ return FALSE;
109+
110+ /* We expect buffer object to be assigned to source */
111+ if (!draw2pix(src->pDrawable))
112+ return FALSE;
113+
114+ /* We expect buffer object to be assigned to destination */
115+ if (!draw2pix(dest->pDrawable))
116+ return FALSE;
117+
118+ return TRUE;
119+}
120+
121+/**
122+ * This callback will be invoked every time xserver needs to combine 2
123+ * pictures. Our special interest is the case when we need to blit draw buffer
124+ * into shadow buffer while performing rotation or reflection. Without
125+ * acceleration such composition will end up in tons of matrix multiplications
126+ * for every pixel, which is obviously very slow. Here we need to detect such
127+ * cases and accelerate the composition on the GPU.
128+ */
129+static void
130+ARMSOCComposite(CARD8 op,
131+ PicturePtr src,
132+ PicturePtr mask,
133+ PicturePtr dest,
134+ INT16 x_src,
135+ INT16 y_src,
136+ INT16 x_mask,
137+ INT16 y_mask,
138+ INT16 x_dest,
139+ INT16 y_dest,
140+ CARD16 width,
141+ CARD16 height)
142+{
143+ ScreenPtr pScreen = dest->pDrawable->pScreen;
144+ PictureScreenPtr ps = GetPictureScreen(pScreen);
145+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
146+ struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
147+ struct armsoc_bo *src_bo = NULL, *dest_bo = NULL;
148+ float xform_matrix[3][3] = {};
149+
150+ Bool can_accelerate =
151+ ARMSOCCanAccelerateComposition(op, src, mask, dest, width, height);
152+
153+
154+ if (can_accelerate) {
155+ /* Transpose, scale & adjust transformation matrix */
156+ int x, y;
157+ for (y = 0; y < 3; ++y)
158+ for (x = 0; x < 3; ++x)
159+ xform_matrix[x][y] =
160+ (float)src->transform->matrix[y][x] / 65536.f;
161+ /*
162+ * TODO: Figure out coordinate system where these sins make sence,
163+ * insted of just reversing them
164+ */
165+ xform_matrix[0][1] = -xform_matrix[0][1];
166+ xform_matrix[1][0] = -xform_matrix[1][0];
167+ }
168+
169+ /* Extract source buffer object */
170+ if (can_accelerate) {
171+ PixmapPtr pm = draw2pix(src->pDrawable);
172+ src_bo = ARMSOCPixmapBo(pm);
173+ }
174+
175+ /* Extract destination buffer object */
176+ if (can_accelerate) {
177+ PixmapPtr pm = draw2pix(dest->pDrawable);
178+ dest_bo = ARMSOCPixmapBo(pm);
179+ }
180+
181+ if (can_accelerate &&
182+ armsoc_repulsion_composite(pARMSOC->repulsion,
183+ src_bo,
184+ dest_bo,
185+ xform_matrix)) {
186+ } else {
187+ /* Fallback to saved compositor if accelerated composition fails */
188+ pARMSOC->composite_proc(op, src, mask, dest,
189+ x_src, y_src, x_mask, y_mask,
190+ x_dest, y_dest, width, height);
191+ }
192+
193+ if (ps->Composite != ARMSOCComposite) {
194+ pARMSOC->composite_proc = ps->Composite;
195+ ps->Composite = ARMSOCComposite;
196+ }
197+}
198+
199 /**
200 * The driver's ScreenInit() function, called at the start of each server
201 * generation. Fill in pScreen, map the frame buffer, save state,
202@@ -986,6 +1119,7 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
203 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
204 VisualPtr visual;
205 xf86CrtcConfigPtr xf86_config;
206+ PictureScreenPtr ps;
207 int j;
208 const char *fbdev;
209 int depth;
210@@ -1174,6 +1308,13 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
211 pARMSOC->lockFD = -1;
212 }
213
214+ pARMSOC->repulsion = armsoc_repulsion_init();
215+
216+ ps = GetPictureScreen(pScreen);
217+ pARMSOC->composite_proc = ps->Composite;
218+
219+ ps->Composite = ARMSOCComposite;
220+
221 TRACE_EXIT();
222 return TRUE;
223
224@@ -1250,6 +1391,8 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL)
225
226 TRACE_ENTER();
227
228+ armsoc_repulsion_release(pARMSOC->repulsion);
229+
230 drmmode_screen_fini(pScrn);
231 drmmode_cursor_fini(pScreen);
232
233@@ -1294,6 +1437,8 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL)
234 pARMSOC->lockFD = -1;
235 }
236
237+ armsoc_repulsion_release(pARMSOC->repulsion);
238+
239 TRACE_EXIT();
240
241 return ret;
242diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h
243index eae76ca..20b0f80 100644
244--- a/src/armsoc_driver.h
245+++ b/src/armsoc_driver.h
246@@ -38,6 +38,7 @@
247 #include "xf86drm.h"
248 #include <errno.h>
249 #include "armsoc_exa.h"
250+#include "armsoc_repulsion.h"
251
252 /* Apparently not used by X server */
253 #define ARMSOC_VERSION 1000
254@@ -183,6 +184,12 @@ struct ARMSOCRec {
255 /* Size of the swap chain. Set to 1 if DRI2SwapLimit unsupported,
256 * driNumBufs if early display enabled, otherwise driNumBufs-1 */
257 unsigned int swap_chain_size;
258+
259+ /* GPU accelerated picture compositor, AKA Repulsion */
260+ struct ARMSOCRepulsion *repulsion;
261+
262+ /* SW (pixman based) picture compositor fallback */
263+ CompositeProcPtr composite_proc;
264 };
265
266 /*
267diff --git a/src/armsoc_dumb.c b/src/armsoc_dumb.c
268index 7e6dbd9..3c16ed2 100644
269--- a/src/armsoc_dumb.c
270+++ b/src/armsoc_dumb.c
271@@ -130,6 +130,14 @@ int armsoc_bo_has_dmabuf(struct armsoc_bo *bo)
272 return bo->dmabuf >= 0;
273 }
274
275+int armsoc_bo_get_dmabuf(struct armsoc_bo *bo)
276+{
277+ if (!armsoc_bo_has_dmabuf(bo))
278+ armsoc_bo_set_dmabuf(bo);
279+
280+ return bo->dmabuf;
281+}
282+
283 struct armsoc_bo *armsoc_bo_new_with_dim(struct armsoc_device *dev,
284 uint32_t width, uint32_t height, uint8_t depth,
285 uint8_t bpp, enum armsoc_buf_type buf_type)
286diff --git a/src/armsoc_dumb.h b/src/armsoc_dumb.h
287index a299ccf..3b687c7 100644
288--- a/src/armsoc_dumb.h
289+++ b/src/armsoc_dumb.h
290@@ -89,6 +89,7 @@ void armsoc_bo_unreference(struct armsoc_bo *bo);
291 int armsoc_bo_set_dmabuf(struct armsoc_bo *bo);
292 void armsoc_bo_clear_dmabuf(struct armsoc_bo *bo);
293 int armsoc_bo_has_dmabuf(struct armsoc_bo *bo);
294+int armsoc_bo_get_dmabuf(struct armsoc_bo *bo);
295 int armsoc_bo_clear(struct armsoc_bo *bo);
296 int armsoc_bo_rm_fb(struct armsoc_bo *bo);
297 int armsoc_bo_resize(struct armsoc_bo *bo, uint32_t new_width,
298diff --git a/src/armsoc_exa.c b/src/armsoc_exa.c
299index a310727..7edf0ac 100644
300--- a/src/armsoc_exa.c
301+++ b/src/armsoc_exa.c
302@@ -161,10 +161,16 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
303 ScrnInfoPtr pScrn = pix2scrn(pPixmap);
304 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
305 enum armsoc_buf_type buf_type = ARMSOC_BO_NON_SCANOUT;
306+ struct armsoc_bo *fb_bo = NULL;
307
308 /* Only modify specified fields, keeping all others intact. */
309- if (pPixData)
310+ if (pPixData) {
311 pPixmap->devPrivate.ptr = pPixData;
312+ if (pARMSOC->shadow && pPixData == armsoc_bo_map(pARMSOC->shadow))
313+ fb_bo = pARMSOC->shadow;
314+ else if (pPixData == armsoc_bo_map(pARMSOC->scanout))
315+ fb_bo = pARMSOC->scanout;
316+ }
317
318 if (devKind > 0)
319 pPixmap->devKind = devKind;
320@@ -173,7 +179,7 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
321 * We can't accelerate this pixmap, and don't ever want to
322 * see it again..
323 */
324- if (pPixData && pPixData != armsoc_bo_map(pARMSOC->scanout)) {
325+ if (pPixData && fb_bo && pPixData != armsoc_bo_map(fb_bo)) {
326 /* scratch-pixmap (see GetScratchPixmapHeader()) gets recycled,
327 * so could have a previous bo!
328 * Pixmap drops ref on its old bo */
329@@ -185,10 +191,10 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
330 }
331
332 /* Replacing the pixmap's current bo with the scanout bo */
333- if (pPixData == armsoc_bo_map(pARMSOC->scanout) && priv->bo != pARMSOC->scanout) {
334+ if (fb_bo && pPixData == armsoc_bo_map(fb_bo) && priv->bo != fb_bo) {
335 struct armsoc_bo *old_bo = priv->bo;
336
337- priv->bo = pARMSOC->scanout;
338+ priv->bo = fb_bo;
339 /* pixmap takes a ref on its new bo */
340 armsoc_bo_reference(priv->bo);
341
342@@ -225,7 +231,9 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
343 if (!pPixmap->drawable.width || !pPixmap->drawable.height)
344 return TRUE;
345
346- assert(priv->bo);
347+ if(!priv->bo)
348+ return FALSE;
349+
350 if (armsoc_bo_width(priv->bo) != pPixmap->drawable.width ||
351 armsoc_bo_height(priv->bo) != pPixmap->drawable.height ||
352 armsoc_bo_bpp(priv->bo) != pPixmap->drawable.bitsPerPixel) {
353diff --git a/src/armsoc_repulsion.c b/src/armsoc_repulsion.c
354new file mode 100644
355index 0000000..1a7c0cd
356--- /dev/null
357+++ b/src/armsoc_repulsion.c
358@@ -0,0 +1,624 @@
359+/*
360+ * Copyright (C) 2024 AMD, Inc.
361+ *
362+ * Permission is hereby granted, free of charge, to any person obtaining a
363+ * copy of this software and associated documentation files (the "Software"),
364+ * to deal in the Software without restriction, including without limitation
365+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
366+ * and/or sell copies of the Software, and to permit persons to whom the
367+ * Software is furnished to do so, subject to the following conditions:
368+ *
369+ * The above copyright notice and this permission notice (including the next
370+ * paragraph) shall be included in all copies or substantial portions of the
371+ * Software.
372+ *
373+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
374+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
375+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
376+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
377+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
378+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
379+ * SOFTWARE.
380+ *
381+ * Author: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
382+ *
383+ */
384+
385+#include "armsoc_repulsion.h"
386+
387+#include <stdlib.h>
388+#include <drm_fourcc.h>
389+
390+#define EGL_GL_PROTOTYPES 1
391+#include <EGL/egl.h>
392+#define EGL_EGLEXT_PROTOTYPES 1
393+#include <EGL/eglext.h>
394+#include <GLES2/gl2.h>
395+#define GL_GLEXT_PROTOTYPES 1
396+#include <GLES2/gl2ext.h>
397+
398+#include <xf86.h>
399+
400+/* -----------------------------------------------------------------------------
401+ * Utilities
402+ */
403+
404+#define INFO_LOG(fmt, ...) \
405+do { xf86DrvMsg(0, X_INFO, fmt "\n", ##__VA_ARGS__); } while (0)
406+
407+#define WARN_LOG(fmt, ...) \
408+do { xf86DrvMsg(0, X_WARNING, "WARNING: " fmt "\n", ##__VA_ARGS__); } while (0)
409+
410+#define ERROR_LOG(fmt, ...) \
411+do { xf86DrvMsg(0, X_ERROR, "ERROR: " fmt "\n", ##__VA_ARGS__); } while (0)
412+
413+/**
414+ * struct RepulsiveVertex - vertex data used for rendering
415+ * @pos: vertex position in the screen coordinate space
416+ * @uv: texture coordinate bound to this vertex
417+ */
418+struct RepulsiveVertex {
419+ GLfloat pos[3];
420+ GLfloat uv[2];
421+};
422+
423+/**
424+ * struct ARMSOCRepulsion - GPU acceleration data
425+ * @egl: EGL specific bits
426+ * @egl.display: EGL display connection
427+ * @egl.context: EGL context
428+ * @egl.surface: primary EGL surface
429+ * @gles: OpenGL ES related bits
430+ * @gles.vbo: Vertex buffer object
431+ * @gles.ibo: Index buffer object
432+ * @gles.texture: External texture object
433+ * @gles.proj_location: Shader location for projection matrix
434+ * @gles.xform_location: Shader location for transformation matrix
435+ * @gles.vertices: Array of vertices used in rendering
436+ */
437+struct ARMSOCRepulsion {
438+ struct {
439+ EGLDisplay display;
440+ EGLContext context;
441+ EGLSurface surface;
442+ } egl;
443+ struct {
444+ GLuint vbo;
445+ GLuint ibo;
446+ GLuint texture;
447+ GLuint program;
448+ GLint proj_location;
449+ GLint xform_location;
450+ struct RepulsiveVertex vertices[4];
451+ } gles;
452+};
453+
454+/* -----------------------------------------------------------------------------
455+ * GLES2 Functions
456+ */
457+
458+static const char *vertex_shader = " \
459+precision highp float; \
460+ \
461+uniform mat3 u_projection; \
462+uniform mat3 u_transform; \
463+attribute vec3 a_position; \
464+attribute vec2 a_texcoord; \
465+ \
466+varying vec2 v_texcoord; \
467+ \
468+void main() \
469+{ \
470+ gl_Position.xyz = u_transform * u_projection * a_position; \
471+ gl_Position.w = 1.0; \
472+ v_texcoord = a_texcoord; \
473+} \
474+";
475+
476+static const char *fragment_shader = " \
477+#extension GL_OES_EGL_image_external : require\n \
478+precision highp float; \
479+ \
480+uniform samplerExternalOES texture; \
481+varying vec2 v_texcoord; \
482+ \
483+void main() \
484+{ \
485+ gl_FragColor = texture2D(texture, v_texcoord); \
486+} \
487+";
488+
489+#define SHADER_POSITION_ATTR_SLOT 0
490+#define SHADER_TEX_COOR_ATTR_SLOT 1
491+
492+static void armsoc_repulsion_gles_log(GLenum source, GLenum type, GLuint id,
493+ GLenum severity, GLsizei length,
494+ const GLchar *message, const void *data)
495+{
496+ switch (severity) {
497+ case GL_DEBUG_SEVERITY_HIGH_KHR:
498+ ERROR_LOG("GLES2: %s", message);
499+ break;
500+ case GL_DEBUG_SEVERITY_MEDIUM_KHR:
501+ WARN_LOG("GLES2: %s", message);
502+ break;
503+ default:
504+ INFO_LOG("GLES2: %s", message);
505+ };
506+}
507+
508+static const char* gles_error_str(GLenum err)
509+{
510+ switch (err) {
511+ case GL_NO_ERROR: return "no error";
512+ case GL_INVALID_ENUM: return "invalid enum";
513+ case GL_INVALID_VALUE: return "invalid value";
514+ case GL_INVALID_OPERATION: return "invalid operation";
515+ case GL_OUT_OF_MEMORY: return "out of memory";
516+ case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid fb operation";
517+ default: return "unknowm error";
518+ }
519+};
520+
521+static int armsoc_repulsion_compile_shader(struct ARMSOCRepulsion *repulsion)
522+{
523+ GLuint vs, fs;
524+ GLint status, texture;
525+ GLenum err;
526+
527+ vs = glCreateShader(GL_VERTEX_SHADER);
528+ if (!vs) {
529+ err = glGetError();
530+ return err == GL_NO_ERROR ? -1 : err;
531+ }
532+ glShaderSource(vs, 1, &vertex_shader, NULL);
533+ glCompileShader(vs);
534+ glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
535+ if (status == GL_FALSE) {
536+ GLint max_len = 1024;
537+ GLchar err_log[1024];
538+ glGetShaderInfoLog(vs, max_len, &max_len, &err_log[0]);
539+ ERROR_LOG("VS: %s", err_log);
540+ err = glGetError();
541+ return err == GL_NO_ERROR ? -1 : err;
542+ }
543+
544+ fs = glCreateShader(GL_FRAGMENT_SHADER);
545+ if (!fs) {
546+ err = glGetError();
547+ return err == GL_NO_ERROR ? -1 : err;
548+ }
549+ glShaderSource(fs, 1, &fragment_shader, NULL);
550+ glCompileShader(fs);
551+ glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
552+ if (status == GL_FALSE) {
553+ err = glGetError();
554+ return err == GL_NO_ERROR ? -1 : err;
555+ }
556+
557+ repulsion->gles.program = glCreateProgram();
558+ if (!repulsion->gles.program) {
559+ err = glGetError();
560+ return err == GL_NO_ERROR ? -1 : err;
561+ }
562+ glAttachShader(repulsion->gles.program, vs);
563+ glAttachShader(repulsion->gles.program, fs);
564+ glBindAttribLocation(repulsion->gles.program, SHADER_POSITION_ATTR_SLOT,
565+ "a_position");
566+ glBindAttribLocation(repulsion->gles.program, SHADER_TEX_COOR_ATTR_SLOT,
567+ "a_texcoord");
568+ glLinkProgram(repulsion->gles.program);
569+ glDetachShader(repulsion->gles.program, vs);
570+ glDetachShader(repulsion->gles.program, fs);
571+ glGetProgramiv(repulsion->gles.program, GL_LINK_STATUS, &status);
572+ if (status == GL_FALSE) {
573+ err = glGetError();
574+ return err == GL_NO_ERROR ? -1 : err;
575+ }
576+ glUseProgram(repulsion->gles.program);
577+ glEnableVertexAttribArray(SHADER_POSITION_ATTR_SLOT);
578+ glEnableVertexAttribArray(SHADER_TEX_COOR_ATTR_SLOT);
579+
580+ repulsion->gles.proj_location =
581+ glGetUniformLocation(repulsion->gles.program, "u_projection");
582+ repulsion->gles.xform_location =
583+ glGetUniformLocation(repulsion->gles.program, "u_transform");
584+
585+ texture = glGetUniformLocation(repulsion->gles.program, "texture");
586+ glUniform1i(texture, 0);
587+ glActiveTexture(GL_TEXTURE0);
588+
589+ return GL_NO_ERROR;
590+}
591+
592+static int armsoc_repulsion_create_vbo(struct ARMSOCRepulsion *repulsion)
593+{
594+ glGenBuffers(1, &repulsion->gles.vbo);
595+ glBindBuffer(GL_ARRAY_BUFFER, repulsion->gles.vbo);
596+
597+ return GL_NO_ERROR;
598+}
599+
600+static int armsoc_repulsion_create_ibo(struct ARMSOCRepulsion *repulsion)
601+{
602+ static const GLushort indices[] = {0, 1, 2, 0, 2, 3};
603+
604+ glGenBuffers(1, &repulsion->gles.ibo);
605+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, repulsion->gles.ibo);
606+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,
607+ GL_STATIC_DRAW);
608+
609+ return GL_NO_ERROR;
610+}
611+
612+static int armsoc_repulsion_create_texture(struct ARMSOCRepulsion *repulsion)
613+{
614+ glGenTextures(1, &repulsion->gles.texture);
615+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, repulsion->gles.texture);
616+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
617+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
618+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
619+ GL_CLAMP_TO_EDGE);
620+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
621+ GL_CLAMP_TO_EDGE);
622+
623+ return GL_NO_ERROR;
624+}
625+
626+static int armsoc_repulsion_init_gles(struct ARMSOCRepulsion *repulsion)
627+{
628+ int rc;
629+
630+ glEnable(GL_DEBUG_OUTPUT_KHR);
631+ glDebugMessageCallbackKHR(armsoc_repulsion_gles_log, repulsion);
632+
633+ rc = armsoc_repulsion_compile_shader(repulsion);
634+ if (rc != GL_NO_ERROR) {
635+ ERROR_LOG("Failed to compile shader: 0x%04x (%s)",
636+ rc, gles_error_str(rc));
637+ return rc;
638+ }
639+
640+ rc = armsoc_repulsion_create_vbo(repulsion);
641+ if (rc != GL_NO_ERROR) {
642+ ERROR_LOG("Failed to create vertex buffer: 0x%04x (%s)",
643+ rc, gles_error_str(rc));
644+ return rc;
645+ }
646+
647+ rc = armsoc_repulsion_create_ibo(repulsion);
648+ if (rc != GL_NO_ERROR) {
649+ ERROR_LOG("Failed to create index buffer: 0x%04x (%s)",
650+ rc, gles_error_str(rc));
651+ return rc;
652+ }
653+
654+ rc = armsoc_repulsion_create_texture(repulsion);
655+ if (rc != GL_NO_ERROR) {
656+ ERROR_LOG("Failed to create texture: 0x%04x (%s)",
657+ rc, gles_error_str(rc));
658+ return rc;
659+ }
660+
661+ return GL_NO_ERROR;
662+}
663+
664+static void armsoc_repulsion_release_texture(struct ARMSOCRepulsion *repulsion)
665+{
666+ glDeleteTextures(1, &repulsion->gles.texture);
667+}
668+
669+static void armsoc_repulsion_release_ibo(struct ARMSOCRepulsion *repulsion)
670+{
671+ glDeleteBuffers(1, &repulsion->gles.ibo);
672+}
673+
674+static void armsoc_repulsion_release_vbo(struct ARMSOCRepulsion *repulsion)
675+{
676+ glDeleteBuffers(1, &repulsion->gles.vbo);
677+}
678+
679+static void armsoc_repulsion_release_shader(struct ARMSOCRepulsion *repulsion)
680+{
681+ glDeleteProgram(repulsion->gles.program);
682+}
683+
684+static void armsoc_repulsion_release_gles(struct ARMSOCRepulsion *repulsion)
685+{
686+ armsoc_repulsion_release_texture(repulsion);
687+ armsoc_repulsion_release_ibo(repulsion);
688+ armsoc_repulsion_release_vbo(repulsion);
689+ armsoc_repulsion_release_shader(repulsion);
690+}
691+
692+/* -----------------------------------------------------------------------------
693+ * EGL Functions
694+ */
695+
696+static const char* egl_error_str(EGLint err)
697+{
698+ switch (err) {
699+ case EGL_SUCCESS: return "no error";
700+ case EGL_NOT_INITIALIZED: return "not initialized";
701+ case EGL_BAD_ACCESS: return "bad access";
702+ case EGL_BAD_ALLOC: return "bad alloc";
703+ case EGL_BAD_CONFIG: return "bad config";
704+ case EGL_BAD_CONTEXT: return "bad context";
705+ case EGL_BAD_CURRENT_SURFACE: return "bad current surface";
706+ case EGL_BAD_DISPLAY: return "bad display";
707+ case EGL_BAD_MATCH: return "bad match";
708+ case EGL_BAD_NATIVE_PIXMAP: return "bad native pixmap";
709+ case EGL_BAD_NATIVE_WINDOW: return "bad native window";
710+ case EGL_BAD_PARAMETER: return "bad parameter";
711+ case EGL_BAD_SURFACE: return "bad surface";
712+ case EGL_CONTEXT_LOST: return "context lost";
713+ default: return "unknowm error";
714+ }
715+};
716+
717+static int armsoc_repulsion_init_egl(struct ARMSOCRepulsion *repulsion)
718+{
719+ static const EGLint config_attrs[] = {
720+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
721+ EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
722+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
723+ EGL_DEPTH_SIZE, 8,
724+ EGL_RED_SIZE, 8,
725+ EGL_GREEN_SIZE, 8,
726+ EGL_BLUE_SIZE, 8,
727+ EGL_ALPHA_SIZE, 8,
728+ EGL_NONE
729+ };
730+ static const EGLint context_attrs[] = {
731+ EGL_CONTEXT_CLIENT_VERSION, 2,
732+ EGL_NONE
733+ };
734+ EGLint count;
735+ EGLConfig config;
736+
737+ repulsion->egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
738+ if (repulsion->egl.display == EGL_NO_DISPLAY)
739+ return eglGetError();
740+
741+ if(!eglInitialize(repulsion->egl.display, NULL, NULL))
742+ return eglGetError();
743+
744+ if (!eglChooseConfig(repulsion->egl.display, config_attrs, &config, 1,
745+ &count))
746+ return eglGetError();
747+
748+ if (!eglBindAPI(EGL_OPENGL_ES_API))
749+ return eglGetError();
750+
751+ repulsion->egl.context = eglCreateContext(repulsion->egl.display, config,
752+ EGL_NO_CONTEXT, context_attrs);
753+ if (repulsion->egl.context == EGL_NO_CONTEXT)
754+ return eglGetError();
755+
756+ repulsion->egl.surface = eglCreatePbufferSurface(repulsion->egl.display,
757+ config, NULL);
758+ if (repulsion->egl.surface == EGL_NO_SURFACE)
759+ return eglGetError();
760+
761+ if (!eglMakeCurrent(repulsion->egl.display, repulsion->egl.surface,
762+ repulsion->egl.surface, repulsion->egl.context))
763+ return eglGetError();
764+
765+ if (!eglSwapInterval(repulsion->egl.display, 0))
766+ return eglGetError();
767+
768+ return EGL_SUCCESS;
769+}
770+
771+static void armsoc_repulsion_release_egl(struct ARMSOCRepulsion *repulsion)
772+{
773+ if (repulsion->egl.surface != EGL_NO_SURFACE)
774+ eglDestroySurface(repulsion->egl.display, repulsion->egl.surface);
775+
776+ if (repulsion->egl.context)
777+ eglDestroyContext(repulsion->egl.display, repulsion->egl.context);
778+
779+ if (repulsion->egl.display)
780+ eglTerminate(repulsion->egl.display);
781+
782+ repulsion->egl.display = EGL_NO_DISPLAY;
783+}
784+
785+static EGLint armsoc_repulsion_guess_bo_format(struct armsoc_bo *bo)
786+{
787+ switch(armsoc_bo_bpp(bo)) {
788+ case 16:
789+ return DRM_FORMAT_RGB565;
790+ case 32:
791+ return DRM_FORMAT_ARGB8888;
792+ default:
793+ return 0;
794+ }
795+}
796+
797+static EGLImageKHR
798+armsoc_repulsion_create_egl_image(struct ARMSOCRepulsion *repulsion,
799+ struct armsoc_bo *bo)
800+{
801+ const EGLint attributes[] = {
802+ EGL_WIDTH, armsoc_bo_width(bo),
803+ EGL_HEIGHT, armsoc_bo_height(bo),
804+ EGL_LINUX_DRM_FOURCC_EXT, armsoc_repulsion_guess_bo_format(bo),
805+ EGL_DMA_BUF_PLANE0_FD_EXT, armsoc_bo_get_dmabuf(bo),
806+ EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
807+ EGL_DMA_BUF_PLANE0_PITCH_EXT, armsoc_bo_pitch(bo),
808+ EGL_NONE
809+ };
810+
811+ return eglCreateImageKHR(repulsion->egl.display, EGL_NO_CONTEXT,
812+ EGL_LINUX_DMA_BUF_EXT, NULL, attributes);
813+}
814+
815+static void
816+armsoc_repulsion_destroy_egl_image(struct ARMSOCRepulsion *repulsion,
817+ EGLImageKHR img)
818+{
819+ eglDestroyImageKHR(repulsion->egl.display, img);
820+}
821+
822+/* -----------------------------------------------------------------------------
823+ * Repulsion API
824+ */
825+
826+bool armsoc_repulsion_composite(struct ARMSOCRepulsion *repulsion,
827+ struct armsoc_bo *src,
828+ struct armsoc_bo *dest,
829+ float xform_matrix[3][3])
830+{
831+ GLuint tex, fbo;
832+ GLenum status;
833+ EGLImageKHR dest_img, src_img;
834+ GLsizei width, height;
835+ static GLfloat proj_matrix[3][3] = {
836+ { 2.f, 0.f, 0.f },
837+ { 0.f, 2.f, 0.f },
838+ { -1.f, -1.f, 0.f },
839+ };
840+
841+ if (!repulsion || !src || !dest)
842+ return false;
843+
844+ dest_img = armsoc_repulsion_create_egl_image(repulsion, dest);
845+ if (dest_img == EGL_NO_IMAGE_KHR) {
846+ EGLint err = eglGetError();
847+ ERROR_LOG("Failed to create dest EGL image: 0x%04x (%s)",
848+ err, egl_error_str(err));
849+ return false;
850+ }
851+ src_img = armsoc_repulsion_create_egl_image(repulsion, src);
852+ if (src_img == EGL_NO_IMAGE_KHR) {
853+ EGLint err = eglGetError();
854+ ERROR_LOG("Failed to create src EGL image: 0x%04x (%s)",
855+ err, egl_error_str(err));
856+ armsoc_repulsion_destroy_egl_image(repulsion, dest_img);
857+ return false;
858+ }
859+
860+ glGenTextures(1, &tex);
861+ glBindTexture(GL_TEXTURE_2D, tex);
862+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, dest_img);
863+
864+ glGenFramebuffers(1, &fbo);
865+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
866+
867+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
868+ GL_TEXTURE_2D, tex, 0);
869+
870+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
871+ if (status != GL_FRAMEBUFFER_COMPLETE) {
872+ ERROR_LOG("Failed to complete framebuffer");
873+ glDeleteFramebuffers(1, &fbo);
874+ glDeleteTextures(1, &tex);
875+ armsoc_repulsion_destroy_egl_image(repulsion, dest_img);
876+ armsoc_repulsion_destroy_egl_image(repulsion, src_img);
877+ return false;
878+ }
879+
880+ width = armsoc_bo_width(dest);
881+ height = armsoc_bo_height(dest);
882+ proj_matrix[0][0] = 2.f / width;
883+ proj_matrix[1][1] = 2.f / height;
884+
885+ glUniformMatrix3fv(repulsion->gles.proj_location, 1, false,
886+ &proj_matrix[0][0]);
887+
888+ glUniformMatrix3fv(repulsion->gles.xform_location, 1, false,
889+ &xform_matrix[0][0]);
890+
891+ glViewport(0, 0, width, height);
892+
893+ glClearColor(0.f, 0.f, 1.f, 1.f);
894+ glClear(GL_COLOR_BUFFER_BIT);
895+
896+ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, src_img);
897+
898+ repulsion->gles.vertices[0].pos[0] = 0.f;
899+ repulsion->gles.vertices[0].pos[1] = height;
900+ repulsion->gles.vertices[0].pos[2] = 1.f;
901+ repulsion->gles.vertices[0].uv[0] = 0.f;
902+ repulsion->gles.vertices[0].uv[1] = 1.f;
903+
904+ repulsion->gles.vertices[1].pos[0] = 0.f;
905+ repulsion->gles.vertices[1].pos[1] = 0.f;
906+ repulsion->gles.vertices[1].pos[2] = 1.f;
907+ repulsion->gles.vertices[1].uv[0] = 0.f;
908+ repulsion->gles.vertices[1].uv[1] = 0.f;
909+
910+ repulsion->gles.vertices[2].pos[0] = width;
911+ repulsion->gles.vertices[2].pos[1] = 0.f;
912+ repulsion->gles.vertices[2].pos[2] = 1.f;
913+ repulsion->gles.vertices[2].uv[0] = 1.f;
914+ repulsion->gles.vertices[2].uv[1] = 0.f;
915+
916+ repulsion->gles.vertices[3].pos[0] = width;
917+ repulsion->gles.vertices[3].pos[1] = height;
918+ repulsion->gles.vertices[3].pos[2] = 1.f;
919+ repulsion->gles.vertices[3].uv[0] = 1.f;
920+ repulsion->gles.vertices[3].uv[1] = 1.f;
921+
922+ glBufferData(GL_ARRAY_BUFFER, sizeof(repulsion->gles.vertices),
923+ repulsion->gles.vertices, GL_STATIC_DRAW);
924+
925+ glVertexAttribPointer(SHADER_POSITION_ATTR_SLOT, 3, GL_FLOAT, GL_FALSE,
926+ sizeof(*repulsion->gles.vertices), (const void *)(0));
927+ glVertexAttribPointer(SHADER_TEX_COOR_ATTR_SLOT, 2, GL_FLOAT, GL_FALSE,
928+ sizeof(*repulsion->gles.vertices),
929+ (const void *)(sizeof(repulsion->gles.vertices->pos)));
930+
931+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
932+
933+ glFinish();
934+
935+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
936+ glDeleteFramebuffers(1, &fbo);
937+ glDeleteTextures(1, &tex);
938+
939+ armsoc_repulsion_destroy_egl_image(repulsion, src_img);
940+ armsoc_repulsion_destroy_egl_image(repulsion, dest_img);
941+
942+ return true;
943+}
944+
945+struct ARMSOCRepulsion *armsoc_repulsion_init(void)
946+{
947+ int rc;
948+ struct ARMSOCRepulsion *repulsion = calloc(1, sizeof(*repulsion));
949+ if (!repulsion) {
950+ ERROR_LOG("Out of memory");
951+ return NULL;
952+ }
953+
954+ rc = armsoc_repulsion_init_egl(repulsion);
955+ if (rc != EGL_SUCCESS) {
956+ ERROR_LOG("Failed to initialize EGL: 0x%04x (%s)",
957+ rc, egl_error_str(rc));
958+ armsoc_repulsion_release(repulsion);
959+ return NULL;
960+ }
961+
962+ rc = armsoc_repulsion_init_gles(repulsion);
963+ if (rc != GL_NO_ERROR) {
964+ ERROR_LOG("Failed to initialize GLES: 0x%04x (%s)",
965+ rc, gles_error_str(rc));
966+ armsoc_repulsion_release(repulsion);
967+ return NULL;
968+ }
969+
970+ INFO_LOG("Repulsion initialized");
971+
972+ return repulsion;
973+}
974+
975+void armsoc_repulsion_release(struct ARMSOCRepulsion *repulsion)
976+{
977+ if (!repulsion)
978+ return;
979+ armsoc_repulsion_release_gles(repulsion);
980+ armsoc_repulsion_release_egl(repulsion);
981+ free(repulsion);
982+}
983diff --git a/src/armsoc_repulsion.h b/src/armsoc_repulsion.h
984new file mode 100644
985index 0000000..b5e57df
986--- /dev/null
987+++ b/src/armsoc_repulsion.h
988@@ -0,0 +1,67 @@
989+/*
990+ * Copyright (C) 2024 AMD, Inc.
991+ *
992+ * Permission is hereby granted, free of charge, to any person obtaining a
993+ * copy of this software and associated documentation files (the "Software"),
994+ * to deal in the Software without restriction, including without limitation
995+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
996+ * and/or sell copies of the Software, and to permit persons to whom the
997+ * Software is furnished to do so, subject to the following conditions:
998+ *
999+ * The above copyright notice and this permission notice (including the next
1000+ * paragraph) shall be included in all copies or substantial portions of the
1001+ * Software.
1002+ *
1003+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1004+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1005+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1006+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1007+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1008+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1009+ * SOFTWARE.
1010+ *
1011+ * Author: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
1012+ *
1013+ */
1014+
1015+#ifndef ARMSOC_REPULSION_H_
1016+#define ARMSOC_REPULSION_H_
1017+
1018+#include <stdbool.h>
1019+#include "armsoc_dumb.h"
1020+
1021+struct ARMSOCRepulsion;
1022+
1023+/**
1024+ * Initialize armsoc repulsion compositor.
1025+ *
1026+ * Return: pointer to new ARMSOCRepulsion object on success, NULL otherwise.
1027+ */
1028+struct ARMSOCRepulsion *armsoc_repulsion_init(void);
1029+
1030+/**
1031+ * Release armsoc repulsion compositor and free all resources.
1032+ * @repulsion: pointer to previously allocated ARMSOCRepulsion object.
1033+ */
1034+void armsoc_repulsion_release(struct ARMSOCRepulsion *repulsion);
1035+
1036+/**
1037+ * Perform 2 image composition.
1038+ * @repulsion: pointer to ARMSOCRepulsion object.
1039+ * @src: source buffer object.
1040+ * @dest: destination buffer object.
1041+ * @xform_matrix: transformation matrix to apply to source image before copying
1042+ * it into destination.
1043+ *
1044+ * This function performs GPU accelerated copy of @src buffer into @dest buffer
1045+ * while applying linear transformation.
1046+ *
1047+ * Return: pointer to new ARMSOCRepulsion object on success, NULL otherwise.
1048+ */
1049+bool armsoc_repulsion_composite(struct ARMSOCRepulsion *repulsion,
1050+ struct armsoc_bo *src,
1051+ struct armsoc_bo *dest,
1052+ float xform_matrix[3][3]);
1053+
1054+
1055+#endif // ARMSOC_REPULSION_H_
1056--
10572.25.1
1058
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch
new file mode 100644
index 00000000..9cc186de
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch
@@ -0,0 +1,110 @@
1From 83047c38b0a9e8cc535eba580ca28497f1bee544 Mon Sep 17 00:00:00 2001
2From: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
3Date: Fri, 19 Jul 2024 14:10:22 -0700
4Subject: [PATCH] xf86-video-armosc: Option to control acceleration
5
6Add xorg config option to enable / disable GPU accelerated picture
7composition. Enable acceleration by default.
8
9Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
10---
11 man/armsoc.man | 6 ++++++
12 src/armsoc_driver.c | 20 +++++++++++++++-----
13 src/armsoc_driver.h | 3 +++
14 3 files changed, 24 insertions(+), 5 deletions(-)
15
16diff --git a/man/armsoc.man b/man/armsoc.man
17index d85c2fa..cdeb19e 100644
18--- a/man/armsoc.man
19+++ b/man/armsoc.man
20@@ -69,6 +69,12 @@ Default: NULL
21 Use the umplock module for cross-process access synchronization. It should be only enabled for Mali400
22 .IP
23 Default: Umplock is Disabled
24+.TP
25+.BI "Option \*qAccelerateComposition\*q \*q" boolean \*q
26+Accelerate picture composition on GPU.
27+.IP
28+Default: Accelerated composition is Enabled
29+
30
31 .SH DRM DEVICE SELECTION
32
33diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
34index f5b8f21..15cc620 100644
35--- a/src/armsoc_driver.c
36+++ b/src/armsoc_driver.c
37@@ -110,6 +110,7 @@ enum {
38 OPTION_DRI_NUM_BUF,
39 OPTION_INIT_FROM_FBDEV,
40 OPTION_UMP_LOCK,
41+ OPTION_ACCELERATE_COMPOSITION,
42 };
43
44 /** Supported options. */
45@@ -122,6 +123,8 @@ static const OptionInfoRec ARMSOCOptions[] = {
46 { OPTION_DRI_NUM_BUF, "DRI2MaxBuffers", OPTV_INTEGER, {-1}, FALSE },
47 { OPTION_INIT_FROM_FBDEV, "InitFromFBDev", OPTV_STRING, {0}, FALSE },
48 { OPTION_UMP_LOCK, "UMP_LOCK", OPTV_BOOLEAN, {0}, FALSE },
49+ { OPTION_ACCELERATE_COMPOSITION, "AccelerateComposition", OPTV_BOOLEAN,
50+ {0}, FALSE },
51 { -1, NULL, OPTV_NONE, {0}, FALSE }
52 };
53
54@@ -871,6 +874,10 @@ ARMSOCPreInit(ScrnInfoPtr pScrn, int flags)
55 armsocDebug = xf86ReturnOptValBool(pARMSOC->pOptionInfo,
56 OPTION_DEBUG, FALSE);
57
58+ /* Should we enable GPU accelerated picture composition? */
59+ pARMSOC->enable_repulsion = xf86ReturnOptValBool(pARMSOC->pOptionInfo,
60+ OPTION_ACCELERATE_COMPOSITION, TRUE);
61+
62 if (!xf86GetOptValInteger(pARMSOC->pOptionInfo, OPTION_DRI_NUM_BUF,
63 &driNumBufs)) {
64 /* Default to double buffering */
65@@ -1119,7 +1126,6 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
66 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
67 VisualPtr visual;
68 xf86CrtcConfigPtr xf86_config;
69- PictureScreenPtr ps;
70 int j;
71 const char *fbdev;
72 int depth;
73@@ -1308,12 +1314,16 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
74 pARMSOC->lockFD = -1;
75 }
76
77- pARMSOC->repulsion = armsoc_repulsion_init();
78+ if (pARMSOC->enable_repulsion) {
79+ PictureScreenPtr ps;
80+
81+ pARMSOC->repulsion = armsoc_repulsion_init();
82
83- ps = GetPictureScreen(pScreen);
84- pARMSOC->composite_proc = ps->Composite;
85+ ps = GetPictureScreen(pScreen);
86+ pARMSOC->composite_proc = ps->Composite;
87
88- ps->Composite = ARMSOCComposite;
89+ ps->Composite = ARMSOCComposite;
90+ }
91
92 TRACE_EXIT();
93 return TRUE;
94diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h
95index 20b0f80..27e978e 100644
96--- a/src/armsoc_driver.h
97+++ b/src/armsoc_driver.h
98@@ -185,6 +185,9 @@ struct ARMSOCRec {
99 * driNumBufs if early display enabled, otherwise driNumBufs-1 */
100 unsigned int swap_chain_size;
101
102+ /* Enable GPU accelerated picture compositor? */
103+ Bool enable_repulsion;
104+
105 /* GPU accelerated picture compositor, AKA Repulsion */
106 struct ARMSOCRepulsion *repulsion;
107
108--
1092.25.1
110
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch
new file mode 100644
index 00000000..8a1a8ca7
--- /dev/null
+++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch
@@ -0,0 +1,141 @@
1From 8c62932a848c3c9eef8b663a24d90026687d5b02 Mon Sep 17 00:00:00 2001
2From: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
3Date: Thu, 13 Jun 2024 17:37:46 -0700
4Subject: [PATCH] xf86-video-armsoc: Add shadow buffer hooks
5
6Add shadow buffer management callbacks. These callbacks are required for
7RandR extension to operate. Implement the shadow buffer as a dumb DRM
8framebuffer. Use the shadow buffer as page flip souce. Fix armsoc_dri2.c
9file mode (drop exec bits).
10
11Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
12---
13 src/armsoc_dri2.c | 3 ++
14 src/armsoc_driver.h | 3 ++
15 src/drmmode_display.c | 65 +++++++++++++++++++++++++++++++++++++++++++
16 3 files changed, 71 insertions(+)
17 mode change 100755 => 100644 src/armsoc_dri2.c
18
19diff --git a/src/armsoc_dri2.c b/src/armsoc_dri2.c
20old mode 100755
21new mode 100644
22index dc502e4..af5d074
23--- a/src/armsoc_dri2.c
24+++ b/src/armsoc_dri2.c
25@@ -853,6 +853,9 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
26 (armsoc_bo_height(src_bo) == armsoc_bo_height(dst_bo));
27
28 if (do_flip) {
29+ if (pARMSOC->shadow)
30+ src_fb_id = armsoc_bo_get_fb(pARMSOC->shadow);
31+
32 DEBUG_MSG("FLIPPING: FB%d -> FB%d", src_fb_id, dst_fb_id);
33 cmd->type = DRI2_FLIP_COMPLETE;
34
35diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h
36index ef2836f..eae76ca 100644
37--- a/src/armsoc_driver.h
38+++ b/src/armsoc_driver.h
39@@ -149,6 +149,9 @@ struct ARMSOCRec {
40 /** Scan-out buffer. */
41 struct armsoc_bo *scanout;
42
43+ /** Rotation shadow buffer */
44+ struct armsoc_bo *shadow;
45+
46 /** Pointer to the options for this screen. */
47 OptionInfoPtr pOptionInfo;
48
49diff --git a/src/drmmode_display.c b/src/drmmode_display.c
50index 39fa75c..f054b3a 100644
51--- a/src/drmmode_display.c
52+++ b/src/drmmode_display.c
53@@ -333,6 +333,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
54 goto cleanup;
55 }
56
57+ if (pARMSOC->shadow)
58+ fb_id = armsoc_bo_get_fb(pARMSOC->shadow);
59+
60 if (crtc->funcs->gamma_set)
61 crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
62 crtc->gamma_blue, crtc->gamma_size);
63@@ -860,6 +863,65 @@ drmmode_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
64 }
65 #endif
66
67+static void*
68+drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
69+{
70+ ScrnInfoPtr pScrn = crtc->scrn;
71+ struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
72+ struct armsoc_bo *bo;
73+ int ret;
74+
75+ bo = armsoc_bo_new_with_dim(pARMSOC->dev, width, height,
76+ pScrn->bitsPerPixel, pScrn->bitsPerPixel, ARMSOC_BO_SCANOUT);
77+ if (!bo)
78+ return NULL;
79+
80+ /* We will use this bo as a scanout, so add it as a framebuffer */
81+ ret = armsoc_bo_add_fb(bo);
82+ if (ret) {
83+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
84+ "failed to add framebuffer: %s\n", strerror(-ret));
85+ armsoc_bo_unreference(bo);
86+ return NULL;
87+ }
88+
89+ pARMSOC->shadow = bo;
90+
91+ return bo;
92+}
93+
94+static PixmapPtr
95+drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
96+{
97+ ScrnInfoPtr pScrn = crtc->scrn;
98+ ScreenPtr pScreen = pScrn->pScreen;
99+ struct armsoc_bo *bo = data;
100+ PixmapPtr pixmap;
101+
102+ pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, armsoc_bo_depth(bo), 0);
103+ if (!pixmap) {
104+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to create pixmap.\n");
105+ return NULL;
106+ }
107+ (*pScreen->ModifyPixmapHeader)(pixmap, armsoc_bo_width(bo),
108+ armsoc_bo_height(bo), armsoc_bo_depth(bo), armsoc_bo_bpp(bo),
109+ armsoc_bo_pitch(bo), armsoc_bo_map(bo));
110+
111+ return pixmap;
112+}
113+
114+static void
115+drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
116+{
117+ ScrnInfoPtr pScrn = crtc->scrn;
118+ struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
119+ struct armsoc_bo *bo = data;
120+
121+ armsoc_bo_unreference(bo);
122+
123+ pARMSOC->shadow = NULL;
124+}
125+
126 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
127 .dpms = drmmode_crtc_dpms,
128 .set_mode_major = drmmode_set_mode_major,
129@@ -870,6 +932,9 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
130 #if 1 == ARMSOC_SUPPORT_GAMMA
131 .gamma_set = drmmode_gamma_set,
132 #endif
133+ .shadow_allocate = drmmode_shadow_allocate,
134+ .shadow_create = drmmode_shadow_create,
135+ .shadow_destroy = drmmode_shadow_destroy,
136 };
137
138
139--
1402.25.1
141
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend
index f7b52f58..9f8af267 100644
--- a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend
+++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend
@@ -2,4 +2,12 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/xf86-video-armsoc:"
2 2
3SRC_URI:append = " file://0001-src-drmmode_xilinx-Add-the-dumb-gem-support-for-Xili.patch \ 3SRC_URI:append = " file://0001-src-drmmode_xilinx-Add-the-dumb-gem-support-for-Xili.patch \
4 file://0001-armsoc_driver.c-Bypass-the-exa-layer-to-free-the-roo.patch \ 4 file://0001-armsoc_driver.c-Bypass-the-exa-layer-to-free-the-roo.patch \
5 " 5 file://0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch \
6 "
7EXTRA_MALI400_SRC = " file://0001-xf86-video-armosc-Accelerate-picture-composition.patch \
8 file://0001-xf86-video-armosc-Option-to-control-acceleration.patch \
9 "
10SRC_URI:append = "${@bb.utils.contains('MACHINE_FEATURES', 'mali400', '${EXTRA_MALI400_SRC}', '', d)}"
11
12DEPENDS:append = "${@bb.utils.contains('MACHINE_FEATURES', 'mali400', ' libmali-xlnx', '', d)}"
13
diff --git a/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend b/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend
index 8a2b7a46..6de745a5 100644
--- a/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend
+++ b/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend
@@ -1,9 +1,9 @@
1SRC_URI = "git://github.com/devicetree-org/lopper.git;branch=v0.2024.x;protocol=https" 1SRC_URI = "git://github.com/devicetree-org/lopper.git;branch=master;protocol=https"
2SRCREV = "4fb08575157d7712e0cd50e9e9c07620bc9f8b4b" 2SRCREV = "c0facd087263a24a83f7fad917884348db03175d"
3 3
4FILESEXTRAPATHS:prepend := "${THISDIR}/lopper:" 4FILESEXTRAPATHS:prepend := "${THISDIR}/lopper:"
5 5
6BASEVERSION = "1.1.0" 6BASEVERSION = "1.2.0"
7 7
8RDEPENDS:${PN} += " \ 8RDEPENDS:${PN} += " \
9 python3-ruamel-yaml \ 9 python3-ruamel-yaml \