diff --git a/.github/workflows/build-main.yaml b/.github/workflows/build-main.yaml index 01137a6ac7..73e359cc63 100644 --- a/.github/workflows/build-main.yaml +++ b/.github/workflows/build-main.yaml @@ -100,8 +100,8 @@ jobs: ### Installation Package Downloads |**Device/Platform**|**Download Package**|**Documentation**| |----|----|----| - |**Anbernic RG351P/M, ODROID Go Advance, ODROID Go Super, Magicx XU10**|[JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3326/)| - |**Anbernic RG353P/M/V/VS, RG503, Powkiddy RK2023, RGB30**|[JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3566/)| + |**Anbernic RG351P/M, Game Console R33S, ODROID Go Advance, ODROID Go Super, Magicx XU10**|[JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3326/)| + |**Anbernic RG353P/M/V/VS, RG503, Powkiddy RK2023, RGB30, RGB10 Max 3**|[JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3566/)| |**Anbernic RG552**|[JELOS-RK3399.aarch64-${{ steps.version.outputs.version }}.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3399.aarch64-${{ steps.version.outputs.version }}.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/RK3399/)| |**Atari VCS, AOKZOE, Ayaneo, Ayn, GPD, and other x86_64 devices**|[JELOS-AMD64.x86_64-${{ steps.version.outputs.version }}.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-AMD64.x86_64-${{ steps.version.outputs.version }}.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/AMD64/)| |**Hardkernel ODROID Go Ultra, Powkiddy RGB10 Max 3 Pro**|[JELOS-S922X.aarch64-${{ steps.version.outputs.version }}-Odroid_GOU.img.gz](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-S922X.aarch64-${{ steps.version.outputs.version }}-Odroid_GOU.img.gz)|[documentation](/documentation/PER_DEVICE_DOCUMENTATION/S922X/)| @@ -120,8 +120,8 @@ jobs: ### Update Package Downloads |**Device/Platform**|**Download Package**| |----|----| - |**Anbernic RG351P/M, ODROID Go Advance, ODROID Go Super, Magicx XU10**|[JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.tar)| - |**Anbernic RG353P/M/V/VS, RG503, Powkiddy RK2023, RGB30**|[JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.tar)| + |**Anbernic RG351P/M, Game Console R33S,ODROID Go Advance, ODROID Go Super, Magicx XU10**|[JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3326.aarch64-${{ steps.version.outputs.version }}.tar)| + |**Anbernic RG353P/M/V/VS, RG503, Powkiddy RK2023, RGB30, RGB10 Max 3**|[JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3566.aarch64-${{ steps.version.outputs.version }}.tar)| |**Anbernic RG552**|[JELOS-RK3399.aarch64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RK3399.aarch64-${{ steps.version.outputs.version }}.tar)| |****Atari VCS, AOKZOE, Ayaneo, Ayn, GPD, and other x86_64 devices****|[JELOS-AMD64.x86_64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-AMD64.x86_64-${{ steps.version.outputs.version }}.tar)| |**Hardkernel ODROID Go Ultra, N2/N2+/N2L, Powkiddy RGB10 Max 3 Pro**|[JELOS-S922X.aarch64-${{ steps.version.outputs.version }}.tar](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-S922X.aarch64-${{ steps.version.outputs.version }}.tar)| diff --git a/README.md b/README.md index 7d9f3dbb1c..708f56a88c 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ JELOS supports a variety of ARM and Intel/AMD based devices. | AYANEO | [AYANEO 2S](http://jelos.org/devices/ayaneo/ayaneo-2) | Amd Ryzen 7 7840U / (x86_64) | Mainline Linux | Radeonsi | Weston + Emulation Station | | Ayn | [Loki Zero](http://jelos.org/devices/ayn/loki-zero) | AMD Athlon Silver 3050e (x86_64) | Mainline Linux | Radeonsi | Weston + Emulation Station | | Ayn | [Loki Max](http://jelos.org/devices/ayn/loki-max) | Amd Ryzen 7 6800U / (x86_64) | Mainline Linux | Radeonsi | Weston + Emulation Station | +| Game Console | [RG33S](http://jelos.org/gameconsole/r33s) | Rockchip RK3326 (ARM) | Mainline Linux | Panfrost | Weston + Emulation Station | | GPD | [Win 4](http://jelos.org/devices/gpd/win4) | Amd Ryzen 7 6800U / (x86_64) | Mainline Linux | Radeonsi | Weston + Emulation Station | | GPD | [Win Max 2 (2022)](http://jelos.org/devices/gpd/win-max-2) | Amd Ryzen 7 6800U / (x86_64) | Mainline Linux| Radeonsi | Weston + Emulation Station | | Hardkernel | [Odroid Go Advance](http://jelos.org/devices/hardkernel/odroid-go-advance) | Rockchip RK3326 (ARM) | Mainline Linux | Panfrost | Weston + Emulation Station | @@ -128,6 +129,7 @@ JELOS supports a variety of ARM and Intel/AMD based devices. | Orange Pi | [Orange Pi 5](http://jelos.org/devices/orange-pi/orange-pi-5) | Rockchip RK3588S / Mali G610 (ARMv8-A) | Rockchip 5.10 BSP Linux | Panfrost | Weston + Emulation Station | | Magicx | [XU10](http://jelos.org/devices/magicx/xu10) | Rockchip RK3326 (ARM) | Mainline Linux | Panfrost | Weston + Emulation Station | | Powkiddy | [RGB10](http://jelos.org/devices/powkiddy/rgb10) | Rockchip RK3326 (ARM) | Mainline Linux | Panfrost | Weston + Emulation Station | +| Powkiddy | [RGB10 Max 3](http://jelos.org/devices/powkiddy/rgb10-max-3) | Rockchip RK3566 (ARM) | Rockchip BSP 4.19 | Mali | KMS/DRM + Emulation Station | | Powkiddy | [RGB10 Max 3 Pro](http://jelos.org/devices/powkiddy/rgb10-max-3-pro) | Amlogic A311D / Mali G52 M4 (ARMv8-A) | Mainline Linux | Mali | Weston + Emulation Station | | Powkiddy | [RGB30](http://jelos.org/devices/powkiddy/rgb30) | Rockchip RK3566 (ARM) | Rockchip BSP 4.19 | Mali | KMS/DRM + Emulation Station | | Powkiddy | [RK2023](http://jelos.org/devices/powkiddy/rk2023) | Rockchip RK3566 (ARM) | Rockchip BSP 4.19 | Mali | KMS/DRM + Emulation Station | diff --git a/config/blocklist b/config/blocklist index 055ae24f24..1925e90926 100644 --- a/config/blocklist +++ b/config/blocklist @@ -14,3 +14,4 @@ retroarch #pinning to release versions for stability. vita3k-sa #Patch updates needed. gzdoom-sa #Stick to release versions. openbor #newer versions break controls, needs research. +gptokeyb #Newer versions break hotkeys diff --git a/config/emulators/cdi.conf b/config/emulators/cdi.conf new file mode 100644 index 0000000000..f8abf259f7 --- /dev/null +++ b/config/emulators/cdi.conf @@ -0,0 +1,11 @@ +SYSTEM_NAME="cdi" +SYSTEM_FULLNAME="CD-i" +SYSTEM_MANUFACTURER="Philips" +SYSTEM_RELEASE="1991" +SYSTEM_HARDWARE="console" +SYSTEM_PATH="/storage/roms/cdi" +SYSTEM_EXTENSION=".chd .cue .iso" +SYSTEM_COMMAND="/usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers=\"%CONTROLLERSCONFIG%\"" +SYSTEM_PLATFORM="cdi" +SYSTEM_THEME="cdi" +SYSTEM_WIKI_PATH="cdi" diff --git a/config/emulators/scv.conf b/config/emulators/scv.conf new file mode 100644 index 0000000000..1f2ae0ea28 --- /dev/null +++ b/config/emulators/scv.conf @@ -0,0 +1,11 @@ +SYSTEM_NAME="scv" +SYSTEM_FULLNAME="Super Cassette Vision" +SYSTEM_MANUFACTURER="EPOCH/YENO" +SYSTEM_RELEASE="1984" +SYSTEM_HARDWARE="console" +SYSTEM_PATH="/storage/roms/scv" +SYSTEM_EXTENSION=".cart .bin .rom .0 .zip" +SYSTEM_COMMAND="/usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers=\"%CONTROLLERSCONFIG%\"" +SYSTEM_PLATFORM="scv" +SYSTEM_THEME="scv" +SYSTEM_WIKI_PATH="scv" diff --git a/config/emulators/x68000.conf b/config/emulators/x68000.conf index 8e73088af0..d627c17b1b 100644 --- a/config/emulators/x68000.conf +++ b/config/emulators/x68000.conf @@ -4,7 +4,7 @@ SYSTEM_MANUFACTURER="Sharp" SYSTEM_RELEASE="1987" SYSTEM_HARDWARE="computer" SYSTEM_PATH="/storage/roms/x68000" -SYSTEM_EXTENSION=".dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z" +SYSTEM_EXTENSION=".dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z" SYSTEM_COMMAND="/usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers=\"%CONTROLLERSCONFIG%\"" SYSTEM_PLATFORM="x68000" SYSTEM_THEME="x68000" diff --git a/distributions/JELOS/options b/distributions/JELOS/options index dcea608973..5f2178c737 100644 --- a/distributions/JELOS/options +++ b/distributions/JELOS/options @@ -44,7 +44,7 @@ # This should be updated to be more dynamic in the future. CLEAN_OS_BASE="emulators u-boot-script system-utils modules quirks autostart jelos" CLEAN_NETWORK="RTL8821CS-firmware" - CLEAN_EMU_32BIT="lib32 box86 flycast-lr pcsx_rearmed-lr arm" + CLEAN_EMU_32BIT="lib32 box86 pcsx_rearmed-lr arm" # Make sure we clean a minimal number of packages for devices with # a BSP kernel and a rotated display when using DEVICE_ROOT. diff --git a/documentation/PER_DEVICE_DOCUMENTATION/AMD64/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/AMD64/SUPPORTED_EMULATORS_AND_CORES.md index b81c85956c..d42fd64dce 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/AMD64/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/AMD64/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -87,6 +88,7 @@ This document describes all available systems emulators and cores available for |Nintendo|Wii (wii)|2006|`wii`|.gcm .iso .gcz .ciso .wbfs .rvz .dol .wad|**dolphin:** dolphin-sa-wii (default)
**retroarch:** dolphin
| |Nintendo|Wii U (wiiu)|2012|`wiiu`|.wud .wux .wua|**cemu:** cemu-sa (default)
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| |Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast (default)
**flycast:** flycast-sa
| |Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**retroarch:** flycast (default)
**flycast:** flycast-sa
| @@ -105,7 +107,7 @@ This document describes all available systems emulators and cores available for |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|**retroarch:** beetle_saturn
**retroarch:** kronos
**mednafen:** ss
| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md index 6ca3378f6d..5d61ef5385 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/RK3326/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -81,9 +82,10 @@ This document describes all available systems emulators and cores available for |Nintendo|Super Nintendo (snes)|1991|`snes`|.smc .fig .sfc .swc .zip .7z|**retroarch:** snes9x (default)
**retroarch:** snes9x2010
**retroarch:** snes9x2002
**retroarch:** snes9x2005_plus
**retroarch:** beetle_supafaust
**retroarch:** bsnes_mercury_performance
**mednafen:** snes_faust
**mednafen:** snes_faust
**mednafen:** snes_faust
| |Nintendo|Virtual Boy (virtualboy)|1995|`virtualboy`|.vb .zip .7z|**retroarch:** beetle_vb (default)
**mednafen:** vb
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| -|Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**flycast:** flycast-sa
**retroarch:** flycast (default)
| -|Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**flycast:** flycast-sa
**retroarch:** flycast (default)
| +|Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**flycast:** flycast-sa
**retroarch:** flycast (default)
| +|Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**flycast:** flycast-sa
**retroarch:** flycast (default)
| |Sega|Game Gear (gamegear)|1990|`gamegear`|.bin .gg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
**retroarch:** smsplus
**mednafen:** gg
| |Sega|Game Gear (Hacks) (ggh)|1990|`gamegearh`|.bin .gg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
**retroarch:** smsplus
**mednafen:** gg
| |Sega|Genesis (genesis)|1989|`genesis`|.bin .gen .md .sg .smd .zip .7z|**retroarch:** genesis_plus_gx (default)
**retroarch:** genesis_plus_gx_wide
**retroarch:** picodrive
| @@ -92,14 +94,14 @@ This document describes all available systems emulators and cores available for |Sega|Mega CD (megacd)|1991|`megacd`|.chd .cue .iso .m3u|**retroarch:** genesis_plus_gx (default)
**retroarch:** picodrive
| |Sega|Mega Drive (megadrive)|1990|`megadrive`|.bin .gen .md .sg .smd .zip .7z|**retroarch:** genesis_plus_gx (default)
**retroarch:** genesis_plus_gx_wide
**retroarch:** picodrive
**mednafen:** md
| |Sega|Mega Drive (megadrive-japan)|1988|`megadrive-japan`|.bin .gen .md .sg .smd .zip .7z|**retroarch:** genesis_plus_gx (default)
**retroarch:** genesis_plus_gx_wide
**retroarch:** picodrive
**mednafen:** md
| -|Sega|Naomi (naomi)|1998|`naomi`|.lst .bin .dat .zip .7z|**flycast:** flycast-sa
**retroarch:** flycast (default)
| +|Sega|Naomi (naomi)|1998|`naomi`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**flycast:** flycast-sa
**retroarch:** flycast (default)
| |Sega|Saturn (saturn)|1994|`saturn`|.cue .chd .iso|**yabasanshiro:** yabasanshiro-sa (default)
**retroarch:** yabasanshiro
| |Sega|Sega 32X (sega32x)|1994|`sega32x`|.32x .smd .bin .md .zip .7z|**retroarch:** picodrive (default)
| |Sega|Sega CD (segacd)|1991|`segacd`|.chd .cue .iso .m3u|**retroarch:** genesis_plus_gx (default)
**retroarch:** picodrive
| |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/documentation/PER_DEVICE_DOCUMENTATION/RK3399/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/RK3399/SUPPORTED_EMULATORS_AND_CORES.md index 5ca2271769..4625fbbc4d 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/RK3399/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/RK3399/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -83,9 +84,10 @@ This document describes all available systems emulators and cores available for |Nintendo|Virtual Boy (virtualboy)|1995|`virtualboy`|.vb .zip .7z|**retroarch:** beetle_vb (default)
**mednafen:** vb
| |Nintendo|Wii (wii)|2006|`wii`|.gcm .iso .gcz .ciso .wbfs .rvz .dol .wad|**dolphin:** dolphin-sa-wii (default)
**retroarch:** dolphin
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| -|Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**flycast:** flycast-sa
**retroarch:** flycast (default)
| -|Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**flycast:** flycast-sa
**retroarch:** flycast (default)
| +|Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**flycast:** flycast-sa
**retroarch:** flycast (default)
| +|Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**flycast:** flycast-sa
**retroarch:** flycast (default)
| |Sega|Game Gear (gamegear)|1990|`gamegear`|.bin .gg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
**retroarch:** smsplus
**mednafen:** gg
| |Sega|Game Gear (Hacks) (ggh)|1990|`gamegearh`|.bin .gg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
**retroarch:** smsplus
**mednafen:** gg
| |Sega|Genesis (genesis)|1989|`genesis`|.bin .gen .md .sg .smd .zip .7z|**retroarch:** genesis_plus_gx (default)
**retroarch:** genesis_plus_gx_wide
**retroarch:** picodrive
**mednafen:** md
| @@ -94,14 +96,14 @@ This document describes all available systems emulators and cores available for |Sega|Mega CD (megacd)|1991|`megacd`|.chd .cue .iso .m3u|**retroarch:** genesis_plus_gx (default)
**retroarch:** picodrive
| |Sega|Mega Drive (megadrive)|1990|`megadrive`|.bin .gen .md .sg .smd .zip .7z|**retroarch:** genesis_plus_gx (default)
**retroarch:** genesis_plus_gx_wide
**retroarch:** picodrive
**mednafen:** md
| |Sega|Mega Drive (megadrive-japan)|1988|`megadrive-japan`|.bin .gen .md .sg .smd .zip .7z|**retroarch:** genesis_plus_gx (default)
**retroarch:** genesis_plus_gx_wide
**retroarch:** picodrive
**mednafen:** md
| -|Sega|Naomi (naomi)|1998|`naomi`|.lst .bin .dat .zip .7z|**flycast:** flycast-sa
**retroarch:** flycast (default)
| +|Sega|Naomi (naomi)|1998|`naomi`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**flycast:** flycast-sa
**retroarch:** flycast (default)
| |Sega|Saturn (saturn)|1994|`saturn`|.cue .chd .iso|**yabasanshiro:** yabasanshiro-sa (default)
**retroarch:** yabasanshiro
| |Sega|Sega 32X (sega32x)|1994|`sega32x`|.32x .smd .bin .md .zip .7z|**retroarch:** picodrive (default)
| |Sega|Sega CD (segacd)|1991|`segacd`|.chd .cue .iso .m3u|**retroarch:** genesis_plus_gx (default)
**retroarch:** picodrive
| |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/documentation/PER_DEVICE_DOCUMENTATION/RK3566-X55/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/RK3566-X55/SUPPORTED_EMULATORS_AND_CORES.md index b6c9644b90..06c4d8f68e 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/RK3566-X55/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/RK3566-X55/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -81,6 +82,7 @@ This document describes all available systems emulators and cores available for |Nintendo|Super Nintendo (snes)|1991|`snes`|.smc .fig .sfc .swc .zip .7z|**retroarch:** snes9x (default)
**retroarch:** snes9x2010
**retroarch:** snes9x2002
**retroarch:** snes9x2005_plus
**retroarch:** beetle_supafaust
**retroarch:** bsnes_mercury_performance
| |Nintendo|Virtual Boy (virtualboy)|1995|`virtualboy`|.vb .zip .7z|**retroarch:** beetle_vb (default)
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| |Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**retroarch:** flycast
**flycast:** flycast-sa
| |Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**retroarch:** flycast
**flycast:** flycast-sa
| @@ -99,7 +101,7 @@ This document describes all available systems emulators and cores available for |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/documentation/PER_DEVICE_DOCUMENTATION/RK3566/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/RK3566/SUPPORTED_EMULATORS_AND_CORES.md index b6c9644b90..06c4d8f68e 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/RK3566/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/RK3566/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -81,6 +82,7 @@ This document describes all available systems emulators and cores available for |Nintendo|Super Nintendo (snes)|1991|`snes`|.smc .fig .sfc .swc .zip .7z|**retroarch:** snes9x (default)
**retroarch:** snes9x2010
**retroarch:** snes9x2002
**retroarch:** snes9x2005_plus
**retroarch:** beetle_supafaust
**retroarch:** bsnes_mercury_performance
| |Nintendo|Virtual Boy (virtualboy)|1995|`virtualboy`|.vb .zip .7z|**retroarch:** beetle_vb (default)
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| |Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**retroarch:** flycast
**flycast:** flycast-sa
| |Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**retroarch:** flycast
**flycast:** flycast-sa
| @@ -99,7 +101,7 @@ This document describes all available systems emulators and cores available for |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/documentation/PER_DEVICE_DOCUMENTATION/RK3588/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/RK3588/SUPPORTED_EMULATORS_AND_CORES.md index d3bfd9bce1..bc55146f19 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/RK3588/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/RK3588/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -83,6 +84,7 @@ This document describes all available systems emulators and cores available for |Nintendo|Virtual Boy (virtualboy)|1995|`virtualboy`|.vb .zip .7z|**retroarch:** beetle_vb (default)
| |Nintendo|Wii (wii)|2006|`wii`|.gcm .iso .gcz .ciso .wbfs .rvz .dol .wad|**dolphin:** dolphin-sa-wii (default)
**retroarch:** dolphin
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| |Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**retroarch:** flycast
**flycast:** flycast-sa
| |Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**retroarch:** flycast
**flycast:** flycast-sa
| @@ -101,7 +103,7 @@ This document describes all available systems emulators and cores available for |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|**retroarch:** beetle_saturn (default)
**mednafen:** ss
| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/documentation/PER_DEVICE_DOCUMENTATION/S922X/SUPPORTED_EMULATORS_AND_CORES.md b/documentation/PER_DEVICE_DOCUMENTATION/S922X/SUPPORTED_EMULATORS_AND_CORES.md index 14ea3ad3be..d91e89ca73 100644 --- a/documentation/PER_DEVICE_DOCUMENTATION/S922X/SUPPORTED_EMULATORS_AND_CORES.md +++ b/documentation/PER_DEVICE_DOCUMENTATION/S922X/SUPPORTED_EMULATORS_AND_CORES.md @@ -41,6 +41,7 @@ This document describes all available systems emulators and cores available for |Commodore|Commodore 64 (c64)|1982|`c64`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x64 (default)
**vicesa:** x64sc
| |Commodore|Commodore PET (pet)|1977|`pet`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xpet (default)
| |Commodore|VIC-20 (vic20)|1980|`vic20`|.20 .a0 .b0 .d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .gz .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_xvic (default)
**vicesa:** xvic
| +|EPOCH/YENO|Super Cassette Vision (scv)|1984|`scv`|.cart .bin .rom .0 .zip|**retroarch:** emuscv (default)
| |Fairchild|Fairchild Channel F (channelf)|1976|`channelf`|.bin .chf .zip .7z|**retroarch:** freechaf (default)
| |id Software|Doom (doom)|1993|`doom`|.doom|**gzdoom:** gzdoom-sa (default)
| |id Software|iDtech (idtech)|1991|`idtech`|.sh|**retroarch:** idtech
| @@ -84,6 +85,7 @@ This document describes all available systems emulators and cores available for |Nintendo|Virtual Boy (virtualboy)|1995|`virtualboy`|.vb .zip .7z|**retroarch:** beetle_vb (default)
| |Nintendo|Wii (wii)|2006|`wii`|.gcm .iso .gcz .ciso .wbfs .rvz .dol .wad|**dolphin:** dolphin-sa-wii (default)
**retroarch:** dolphin
| |Panasonic|3DO (3do)|1993|`3do`|.iso .bin .chd .cue|**retroarch:** opera (default)
| +|Philips|CD-i (cdi)|1991|`cdi`|.chd .cue .iso|**retroarch:** same_cdi (default)
| |Philips|VideoPac (videopac)|1978|`videopac`|.bin .zip .7z|**retroarch:** o2em (default)
| |Sammy|Atomiswave (atomiswave)|2003|`atomiswave`|.lst .bin .dat .zip .7z|**retroarch:** flycast2021
**flycast:** flycast-sa (default)
**retroarch:** flycast
| |Sega|Dreamcast (dreamcast)|1998|`dreamcast`|.cdi .gdi .chd .m3u .cue|**retroarch:** flycast2021
**flycast:** flycast-sa (default)
**retroarch:** flycast
| @@ -102,7 +104,7 @@ This document describes all available systems emulators and cores available for |Sega|SG-1000 (sg-1000)|1983|`sg-1000`|.bin .sg .zip .7z|**retroarch:** gearsystem (default)
**retroarch:** genesis_plus_gx
**retroarch:** picodrive
| |Sega|ST-V (st-v)|1995|`st-v`|.zip .ZIP|| |Sharp|X1 (x1)|1982|`x1`|.dx1 .2d .2hd .tfd .d88d .hdm .xdf .dup .tap .cmd .zip .7z|**retroarch:** x1 (default)
| -|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88d .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| +|Sharp|x68000 (x68000)|1987|`x68000`|.dim .img .d88 .hdm .dup .2hd .xdf .hdf .cmd .m3u .zip .7z|**retroarch:** px68k (default)
| |Sinclair|ZX Spectrum (zxspectrum)|1982|`zxspectrum`|.tzx .tap .z80 .rzx .scl .trd .dsk .zip .7z|**retroarch:** fuse
| |Sinclair|ZX81 (zx81)|1981|`zx81`|.tzx .p .zip .7z|**retroarch:** 81 (default)
| |Smith Engineering|Vectrex (vectrex)|1982|`vectrex`|.bin .gam .vec .zip .7z|**retroarch:** vecx (default)
| diff --git a/packages/apps/fileman/package.mk b/packages/apps/fileman/package.mk index b913565bdd..0d283c71f1 100644 --- a/packages/apps/fileman/package.mk +++ b/packages/apps/fileman/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) PKG_NAME="fileman" -PKG_VERSION="a32294a681036cdb9d2f3707ebc3f2889705960e" +PKG_VERSION="fb39d3c7b8bc89fd7be8c976cfaebb206c67cdcd" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="https://github.com/JustEnoughLinuxOS/fileman" diff --git a/packages/apps/portmaster/package.mk b/packages/apps/portmaster/package.mk index 58bb34ab33..9ccd1d6f8e 100644 --- a/packages/apps/portmaster/package.mk +++ b/packages/apps/portmaster/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) PKG_NAME="portmaster" -PKG_VERSION="8.5.13_1130" +PKG_VERSION="8.5.23_0623" PKG_SITE="https://github.com/PortsMaster/PortMaster-GUI" PKG_URL="${PKG_SITE}/releases/download/${PKG_VERSION}/PortMaster.zip" COMPAT_URL="https://github.com/brooksytech/JelosAddOns/raw/main/compat.zip" diff --git a/packages/apps/portmaster/scripts/portmaster_compatibility.sh b/packages/apps/portmaster/scripts/portmaster_compatibility.sh index cc69546ea3..8afc948cd7 100644 --- a/packages/apps/portmaster/scripts/portmaster_compatibility.sh +++ b/packages/apps/portmaster/scripts/portmaster_compatibility.sh @@ -7,7 +7,7 @@ if [[ "${UI_SERVICE}" =~ weston.service ]]; then case "${QUIRK_DEVICE}" in - "Hardkernel ODROID-GO-Ultra"|"Powkiddy RGB10 MAX 3"|"Hardkernel ODROID-N2*") + "Hardkernel ODROID-GO-Ultra"|"Powkiddy RGB10 MAX 3 Pro"|"Hardkernel ODROID-N2*") #Fixing ports on S922X, exclude FNA games for port in /storage/roms/ports/*.sh; do if ! grep -q FNA "$port"; then @@ -22,9 +22,10 @@ case "${QUIRK_DEVICE}" in rm -rf /storage/roms/ports/*/lib*/libGL* for port in /storage/roms/ports/*.sh; do if grep -q SDL_VIDEO_GL_DRIVER "$port"; then - sed -i '/^export SDL_VIDEO_GL_DRIVER/c\#export SDL_VIDEO_GL_DRIVER"' "$port" + sed -i '/^export SDL_VIDEO_GL_DRIVER/c\#export SDL_VIDEO_GL_DRIVER' "$port" sed -i '/^export SDL_VIDEO_EGL_DRIVER/c\#export SDL_VIDEO_EGL_DRIVER' "$port" echo Fixing: "$port"; + fi done; #Remove S922X fix if exists diff --git a/packages/apps/portmaster/scripts/start_portmaster.sh b/packages/apps/portmaster/scripts/start_portmaster.sh index 03439c45bb..519c8cd9f8 100644 --- a/packages/apps/portmaster/scripts/start_portmaster.sh +++ b/packages/apps/portmaster/scripts/start_portmaster.sh @@ -69,9 +69,6 @@ else xmlstarlet ed --inplace --subnode "/gameList/folder[last()]" --type elem -n hidden -v "true" /storage/roms/ports/gamelist.xml fi -#Make sure permissions are correct in the PortMaster folder -find /storage/roms/ports/ -not -perm 755 -exec chmod 755 {} \; - #Fix compatability for some portmaster ports /usr/bin/portmaster_compatibility.sh diff --git a/packages/apps/portmaster/sources/control.txt b/packages/apps/portmaster/sources/control.txt index 610c74a2f7..9c5d64b892 100644 --- a/packages/apps/portmaster/sources/control.txt +++ b/packages/apps/portmaster/sources/control.txt @@ -30,7 +30,7 @@ case "${QUIRK_DEVICE}" in lres="N" sticks="2" ;; - "Hardkernel ODROID-GO-Ultra"|"Powkiddy RGB10 MAX 3") + "Hardkernel ODROID-GO-Ultra"|"Powkiddy RGB10 MAX 3 Pro") profile="s922x" lres="N" sticks="2" diff --git a/packages/apps/portmaster/sources/mapper.txt b/packages/apps/portmaster/sources/mapper.txt index ab831a56df..7df09ea334 100644 --- a/packages/apps/portmaster/sources/mapper.txt +++ b/packages/apps/portmaster/sources/mapper.txt @@ -56,7 +56,6 @@ function map { "b") TR_NAME="${BBUT}";; "x") TR_NAME="${XBUT}";; "y") TR_NAME="${YBUT}";; - "hotkeyenable") TR_NAME="guide";; "up") TR_NAME="dpup";; "down") TR_NAME="dpdown";; "left") TR_NAME="dpleft";; @@ -78,7 +77,6 @@ function map { "rightanalogdown") TR_NAME="+righty";; "rightanalogright") TR_NAME="+rightx";; *) - echo "Invalid mapping ${INPUT_NAME}." return ;; esac @@ -147,8 +145,6 @@ while IFS=";" read -r NAME GUID; do get_map_suffix if [[ ! -z "${MAPPING}" ]]; then echo "${map_prefix}${MAPPING}${map_suffix}" >> "${CONTROLLER_DB}" - else - echo "Failed to map anything." fi done <<< ${ES_QUERY:1} diff --git a/packages/audio/pipewire/package.mk b/packages/audio/pipewire/package.mk index e5f4c04213..270ce84826 100644 --- a/packages/audio/pipewire/package.mk +++ b/packages/audio/pipewire/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) PKG_NAME="pipewire" -PKG_VERSION="0.3.84" +PKG_VERSION="1.0.1" PKG_LICENSE="LGPL" PKG_SITE="https://pipewire.org" PKG_URL="https://github.com/PipeWire/pipewire/archive/${PKG_VERSION}.tar.gz" diff --git a/packages/audio/pipewire/patches/001-pipewire-pulse.patch b/packages/audio/pipewire/patches/001-pipewire-pulse.patch index b71eae88ef..bb7a5af626 100644 --- a/packages/audio/pipewire/patches/001-pipewire-pulse.patch +++ b/packages/audio/pipewire/patches/001-pipewire-pulse.patch @@ -1,7 +1,7 @@ -diff -rupN pipewire-0.3.84.orig/src/daemon/pipewire-pulse.conf.in pipewire-0.3.84/src/daemon/pipewire-pulse.conf.in ---- pipewire-0.3.84.orig/src/daemon/pipewire-pulse.conf.in 2023-11-13 16:35:56.502690919 +0000 -+++ pipewire-0.3.84/src/daemon/pipewire-pulse.conf.in 2023-11-13 16:36:28.096495134 +0000 -@@ -90,11 +90,11 @@ pulse.properties = { +diff -rupN pipewire-1.0.0.orig/src/daemon/pipewire-pulse.conf.in pipewire-1.0.0/src/daemon/pipewire-pulse.conf.in +--- pipewire-1.0.0.orig/src/daemon/pipewire-pulse.conf.in 2023-12-29 13:41:35.329947857 +0000 ++++ pipewire-1.0.0/src/daemon/pipewire-pulse.conf.in 2023-12-29 13:41:46.850669838 +0000 +@@ -92,11 +92,11 @@ pulse.properties = { #"tcp:[::]:9999" # IPv6 on all addresses #"tcp:127.0.0.1:8888" # IPv4 on a single address # @@ -18,23 +18,17 @@ diff -rupN pipewire-0.3.84.orig/src/daemon/pipewire-pulse.conf.in pipewire-0.3.8 ] #server.dbus-name = "org.pulseaudio.Server" #pulse.min.req = 128/48000 # 2.7ms -diff -rupN pipewire-0.3.84.orig/src/daemon/systemd/system/pipewire.service.in pipewire-0.3.84/src/daemon/systemd/system/pipewire.service.in ---- pipewire-0.3.84.orig/src/daemon/systemd/system/pipewire.service.in 2023-11-13 16:35:56.502690919 +0000 -+++ pipewire-0.3.84/src/daemon/systemd/system/pipewire.service.in 2023-11-13 16:36:28.096495134 +0000 -@@ -15,21 +15,24 @@ Description=PipeWire Multimedia Service - Requires=pipewire.socket - - [Service] --LockPersonality=yes --MemoryDenyWriteExecute=yes --NoNewPrivileges=yes --RestrictNamespaces=yes --SystemCallArchitectures=native --SystemCallFilter=@system-service +diff -rupN pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.service.in pipewire-1.0.0/src/daemon/systemd/system/pipewire.service.in +--- pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.service.in 2023-12-29 13:41:35.329947857 +0000 ++++ pipewire-1.0.0/src/daemon/systemd/system/pipewire.service.in 2023-12-29 13:43:32.217227049 +0000 +@@ -21,15 +21,25 @@ NoNewPrivileges=yes + RestrictNamespaces=yes + SystemCallArchitectures=native + SystemCallFilter=@system-service +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket +User=root Type=simple --AmbientCapabilities=CAP_SYS_NICE + AmbientCapabilities=CAP_SYS_NICE -ExecStart=@PW_BINARY@ +ExecStart=/usr/bin/pipewire Restart=on-failure @@ -53,16 +47,16 @@ diff -rupN pipewire-0.3.84.orig/src/daemon/systemd/system/pipewire.service.in pi +Environment=HOME=/storage [Install] --Also=pipewire.socket -+Also=pipewire-pulse.socket +-Also=pipewire.socket pipewire-manager.socket ++Also=pipewire.socket pipewire-pulse.socket pipewire-manager.socket WantedBy=default.target -diff -rupN pipewire-0.3.84.orig/src/daemon/systemd/system/pipewire.socket pipewire-0.3.84/src/daemon/systemd/system/pipewire.socket ---- pipewire-0.3.84.orig/src/daemon/systemd/system/pipewire.socket 2023-11-13 16:35:56.502690919 +0000 -+++ pipewire-0.3.84/src/daemon/systemd/system/pipewire.socket 2023-11-13 16:36:58.434228383 +0000 -@@ -5,8 +5,8 @@ Description=PipeWire Multimedia System S +diff -rupN pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.socket pipewire-1.0.0/src/daemon/systemd/system/pipewire.socket +--- pipewire-1.0.0.orig/src/daemon/systemd/system/pipewire.socket 2023-12-29 13:41:35.329947857 +0000 ++++ pipewire-1.0.0/src/daemon/systemd/system/pipewire.socket 2023-12-29 13:44:04.291208172 +0000 +@@ -4,8 +4,8 @@ Description=PipeWire Multimedia System S + [Socket] Priority=6 ListenStream=%t/pipewire/pipewire-0 - ListenStream=%t/pipewire/pipewire-0-manager -SocketUser=pipewire -SocketGroup=pipewire +SocketUser=root diff --git a/packages/audio/pipewire/patches/002-revert-pollfd.patch b/packages/audio/pipewire/patches/002-revert-pollfd.patch new file mode 100644 index 0000000000..ddea2e936f --- /dev/null +++ b/packages/audio/pipewire/patches/002-revert-pollfd.patch @@ -0,0 +1,106 @@ +diff -rupN pipewire-1.0.1.orig/pipewire-alsa/alsa-plugins/pcm_pipewire.c pipewire-1.0.1/pipewire-alsa/alsa-plugins/pcm_pipewire.c +--- pipewire-1.0.1.orig/pipewire-alsa/alsa-plugins/pcm_pipewire.c 2024-01-23 20:57:27.818081461 +0000 ++++ pipewire-1.0.1/pipewire-alsa/alsa-plugins/pcm_pipewire.c 2024-01-23 20:57:56.203633317 +0000 +@@ -89,7 +89,7 @@ typedef struct { + + static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io); + +-static int update_active(snd_pcm_ioplug_t *io) ++static int check_active(snd_pcm_ioplug_t *io) + { + snd_pcm_pipewire_t *pw = io->private_data; + snd_pcm_sframes_t avail; +@@ -97,10 +97,7 @@ static int update_active(snd_pcm_ioplug_ + + avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr); + +- if (pw->error > 0) { +- active = true; +- } +- else if (io->state == SND_PCM_STATE_DRAINING) { ++ if (io->state == SND_PCM_STATE_DRAINING) { + active = pw->drained; + } + else if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) { +@@ -108,27 +105,33 @@ static int update_active(snd_pcm_ioplug_ + } + else if (avail >= (snd_pcm_sframes_t)pw->min_avail) { + active = true; +- } +- else { ++ } else { + active = false; + } + if (pw->active != active) { +- uint64_t val; +- + pw_log_trace("%p: avail:%lu min-avail:%lu state:%s hw:%lu appl:%lu active:%d->%d state:%s", + pw, avail, pw->min_avail, snd_pcm_state_name(io->state), + pw->hw_ptr, io->appl_ptr, pw->active, active, + snd_pcm_state_name(io->state)); +- +- pw->active = active; +- if (active) +- spa_system_eventfd_write(pw->system, io->poll_fd, 1); +- else +- spa_system_eventfd_read(pw->system, io->poll_fd, &val); + } + return active; + } + ++ ++static int update_active(snd_pcm_ioplug_t *io) ++{ ++ snd_pcm_pipewire_t *pw = io->private_data; ++ pw->active = check_active(io); ++ uint64_t val; ++ ++ if (pw->active || pw->error < 0) ++ spa_system_eventfd_write(pw->system, io->poll_fd, 1); ++ else ++ spa_system_eventfd_read(pw->system, io->poll_fd, &val); ++ ++ return pw->active; ++} ++ + static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw) + { + if (pw == NULL) +@@ -159,6 +162,15 @@ static int snd_pcm_pipewire_close(snd_pc + return 0; + } + ++static int snd_pcm_pipewire_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfds, unsigned int space) ++{ ++ snd_pcm_pipewire_t *pw = io->private_data; ++ update_active(io); ++ pfds->fd = pw->fd; ++ pfds->events = POLLIN | POLLERR | POLLNVAL; ++ return 1; ++} ++ + static int snd_pcm_pipewire_poll_revents(snd_pcm_ioplug_t *io, + struct pollfd *pfds, unsigned int nfds, + unsigned short *revents) +@@ -171,10 +183,10 @@ static int snd_pcm_pipewire_poll_revents + return pw->error; + + *revents = pfds[0].revents & ~(POLLIN | POLLOUT); +- if (pfds[0].revents & POLLIN && update_active(io)) ++ if (pfds[0].revents & POLLIN && check_active(io)) { + *revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN; +- +- pw_log_trace_fp("poll %d", *revents); ++ update_active(io); ++ } + + return 0; + } +@@ -899,6 +911,7 @@ static snd_pcm_ioplug_callback_t pipewir + .delay = snd_pcm_pipewire_delay, + .drain = snd_pcm_pipewire_drain, + .prepare = snd_pcm_pipewire_prepare, ++ .poll_descriptors = snd_pcm_pipewire_poll_descriptors, + .poll_revents = snd_pcm_pipewire_poll_revents, + .hw_params = snd_pcm_pipewire_hw_params, + .sw_params = snd_pcm_pipewire_sw_params, diff --git a/packages/audio/pulseaudio/package.mk b/packages/audio/pulseaudio/package.mk index 0cee45008a..b3005ab5ca 100644 --- a/packages/audio/pulseaudio/package.mk +++ b/packages/audio/pulseaudio/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="pulseaudio" -PKG_VERSION="16.1" +PKG_VERSION="17.0" PKG_LICENSE="GPL" PKG_SITE="http://pulseaudio.org/" PKG_URL="http://www.freedesktop.org/software/pulseaudio/releases/${PKG_NAME}-${PKG_VERSION}.tar.xz" diff --git a/packages/audio/wireplumber/package.mk b/packages/audio/wireplumber/package.mk index 231f3b1cd6..e048dca173 100644 --- a/packages/audio/wireplumber/package.mk +++ b/packages/audio/wireplumber/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) PKG_NAME="wireplumber" -PKG_VERSION="0.4.15" +PKG_VERSION="0.4.17" PKG_LICENSE="MIT" PKG_SITE="https://gitlab.freedesktop.org/pipewire/wireplumber" PKG_URL="https://gitlab.freedesktop.org/pipewire/wireplumber/-/archive/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" @@ -21,6 +21,7 @@ PKG_MESON_OPTS_TARGET="-Dintrospection=disabled \ post_makeinstall_target() { + mkdir -p ${INSTALL}/usr/share/wireplumber/{main.lua.d,bluetooth.lua.d} # ref https://gitlab.freedesktop.org/pipewire/wireplumber/-/commit/0da29f38181e391160fa8702623050b8544ec775 cat > ${INSTALL}/usr/share/wireplumber/main.lua.d/89-disable-session-dbus-dependent-features.lua << EOF alsa_monitor.properties["alsa.reserve"] = false diff --git a/packages/emulators/libretro/emuscv-lr/package.mk b/packages/emulators/libretro/emuscv-lr/package.mk new file mode 100644 index 0000000000..70bd4ed950 --- /dev/null +++ b/packages/emulators/libretro/emuscv-lr/package.mk @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="emuscv-lr" +PKG_VERSION="dfce10df090ce3f5eb23bdbee289702ec1478246" +#PKG_ARCH="aarch64" +PKG_SITE="https://gitlab.com/MaaaX-EmuSCV/libretro-emuscv" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="An EPOCH/YENO Super Cassette Vision (1984) home video game emulator for Libretro" +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="-C . platform=unix" + +pre_configure_target() { + export TERM=xterm + CXXFLAGS+=" -I$(get_build_dir glibc)/sysdeps/unix/sysv/linux/x86" +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_BUILD}/emuscv_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/packages/emulators/libretro/emuscv-lr/patches/emuscv_platform.patch b/packages/emulators/libretro/emuscv-lr/patches/emuscv_platform.patch new file mode 100644 index 0000000000..96cac8656d --- /dev/null +++ b/packages/emulators/libretro/emuscv-lr/patches/emuscv_platform.patch @@ -0,0 +1,16 @@ +diff --git a/Makefile.libretro b/Makefile.libretro +index e1df23a..0392c0c 100644 +--- a/Makefile.libretro ++++ b/Makefile.libretro +@@ -70,11 +70,6 @@ ifneq (,$(findstring unix,$(platform))) + ifneq (,$(findstring Haiku,$(shell uname -s))) + LDFLAGS += -lnetwork -lroot + endif +- CC = gcc +- CXX = gcc +- LDFLAGS += -I/usr/include/SDL2 -L/usr/lib/x86_64-linux-gnu -lSDL2 +- CFLAGS += -I/usr/include/SDL2 `sdl2-config --cflags` +- CXXFLAGS += -I/usr/include/SDL2 `sdl2-config --cflags` + + # Raspberry Pi + ifneq (,$(findstring rpi,$(platform))) diff --git a/packages/emulators/libretro/flycast2021-lr/patches/RK3326/000-platform.patch b/packages/emulators/libretro/flycast2021-lr/patches/RK3326/000-platform.patch index 4fa747a115..2dad924ad0 100644 --- a/packages/emulators/libretro/flycast2021-lr/patches/RK3326/000-platform.patch +++ b/packages/emulators/libretro/flycast2021-lr/patches/RK3326/000-platform.patch @@ -28,7 +28,7 @@ diff -rupN flycast.orig/Makefile flycast/Makefile + -fuse-linker-plugin \ + -fno-stack-protector -fno-ident -fomit-frame-pointer \ + -fmerge-all-constants -ffast-math -funroll-all-loops \ -+ -mcpu=cortex-a35 -mtune=cortex-a35 ++ -mcpu=cortex-a35 -mtune=cortex-a35 -mno-outline-atomics + CXXFLAGS += $(CFLAGS) + LDFLAGS += -mcpu=cortex-a35 -mtune=cortex-a35 -Ofast -flto -fuse-linker-plugin PLATFORM_EXT := unix diff --git a/packages/emulators/libretro/flycast2021-lr/patches/RK3399/000-platform.patch b/packages/emulators/libretro/flycast2021-lr/patches/RK3399/000-platform.patch index a5b565cee8..046bf71916 100644 --- a/packages/emulators/libretro/flycast2021-lr/patches/RK3399/000-platform.patch +++ b/packages/emulators/libretro/flycast2021-lr/patches/RK3399/000-platform.patch @@ -28,7 +28,7 @@ diff -rupN flycast.orig/Makefile flycast/Makefile + -fuse-linker-plugin \ + -fno-stack-protector -fno-ident -fomit-frame-pointer \ + -fmerge-all-constants -ffast-math -funroll-all-loops \ -+ -mcpu=cortex-a72 -mtune=cortex-a72 ++ -mcpu=cortex-a72 -mtune=cortex-a72 -mno-outline-atomics + CXXFLAGS += $(CFLAGS) + LDFLAGS += -mcpu=cortex-a72 -mtune=cortex-a72 -Ofast -flto -fuse-linker-plugin PLATFORM_EXT := unix diff --git a/packages/emulators/libretro/same_cdi-lr/package.mk b/packages/emulators/libretro/same_cdi-lr/package.mk new file mode 100644 index 0000000000..e574bd2392 --- /dev/null +++ b/packages/emulators/libretro/same_cdi-lr/package.mk @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present AmberELEC (https://github.com/AmberELEC) + +PKG_NAME="same_cdi-lr" +PKG_VERSION="54cf493c2dee4c46666059c452f8aaaa0bd7c8e0" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/libretro/same_cdi" +PKG_URL="${PKG_SITE}.git" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="SAME_CDI is a Single Arcade/Machine Emulator for libretro" +PKG_TOOLCHAIN="make" + +PKG_MAKE_OPTS_TARGET="REGENIE=1 \ + VERBOSE=1 \ + NOWERROR=1 \ + OPENMP=1 \ + CROSS_BUILD=1 \ + TOOLS=0 \ + RETRO=1 \ + PTR64=0 \ + NOASM=0 \ + PYTHON_EXECUTABLE=python3 \ + CONFIG=libretro \ + LIBRETRO_OS=unix \ + LIBRETRO_CPU= \ + PLATFORM=arm64 \ + ARCH= \ + TARGET=mame \ + OSD=retro \ + USE_SYSTEM_LIB_EXPAT=1 \ + USE_SYSTEM_LIB_ZLIB=1 \ + USE_SYSTEM_LIB_FLAC=1 \ + USE_SYSTEM_LIB_SQLITE3=1" + +pre_configure_target() { + sed -i "s/-static-libstdc++//g" scripts/genie.lua +} + +make_target() { + unset ARCH + unset DISTRO + unset PROJECT + export ARCHOPTS="-D__aarch64__ -DASMJIT_BUILD_X86" + make -f Makefile.libretro ${PKG_MAKE_OPTS_TARGET} OVERRIDE_CC=${CC} OVERRIDE_CXX=${CXX} OVERRIDE_LD=${LD} AR=${AR} ${MAKEFLAGS} +} + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/lib/libretro + cp same_cdi_libretro.so ${INSTALL}/usr/lib/libretro/ +} diff --git a/packages/emulators/libretro/same_cdi-lr/patches/001-gcc13-fix.patch b/packages/emulators/libretro/same_cdi-lr/patches/001-gcc13-fix.patch new file mode 100644 index 0000000000..d2a6c8c43f --- /dev/null +++ b/packages/emulators/libretro/same_cdi-lr/patches/001-gcc13-fix.patch @@ -0,0 +1,12 @@ +diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h +index 4a06b705..506ba834 100644 +--- a/src/osd/modules/lib/osdlib.h ++++ b/src/osd/modules/lib/osdlib.h +@@ -18,6 +18,7 @@ + + #include + #include ++#include + #include + #include + #include diff --git a/packages/emulators/libretro/same_cdi-lr/patches/mame-crosscompile.patch b/packages/emulators/libretro/same_cdi-lr/patches/mame-crosscompile.patch new file mode 100644 index 0000000000..49f1ff3763 --- /dev/null +++ b/packages/emulators/libretro/same_cdi-lr/patches/mame-crosscompile.patch @@ -0,0 +1,54 @@ +--- a/3rdparty/genie/build/gmake.linux/genie.make 2018-08-11 00:17:44.000000000 +0200 ++++ b/3rdparty/genie/build/gmake.linux/genie.make 2019-04-03 11:57:27.671223016 +0200 +@@ -28,8 +28,8 @@ + RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0 + endif + +-CC = gcc +-CXX = g++ ++CC = $(HOST_CC) ++CXX = $(HOST_CXX) + AR = ar + + ifndef RESCOMP +@@ -50,12 +50,12 @@ + INCLUDES += -I"../../src/host/lua-5.3.0/src" + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough +- ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_CFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_CXXFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_OBJCFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough ++ ALL_OBJCPPFLAGS += $(ALL_CPPFLAGS) $(ARCH) -Wall -Wextra -Os $(MPARAM) -Wno-implicit-fallthrough + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) +- ALL_LDFLAGS += $(LDFLAGS) -L"." -s -rdynamic ++ ALL_LDFLAGS += -L"." -s -rdynamic + LIBDEPS += + LDDEPS += + LDRESP = +--- a/3rdparty/genie/src/host/scripts.c 2019-05-21 22:41:14.207745861 +0200 ++++ b/3rdparty/genie/src/host/scripts.c 2019-05-21 22:42:43.159893481 +0200 +@@ -147,7 +147,7 @@ + + /* tools/gcc.lua */ + "premake.gcc = { }\npremake.gcc.cc = \"gcc\"\npremake.gcc.cxx = \"g++\"\npremake.gcc.ar = \"ar\"\npremake.gcc.rc = \"windres\"\npremake.gcc.llvm = false\nlocal cflags =\n{\nEnableSSE = \"-msse\",\nEnableSSE2 = \"-msse2\",\nEnableAVX = \"-mavx\",\nEnableAVX2 = \"-mavx2\",\nPedanticWarnings = \"-Wall -Wextra -pedantic\",\nExtraWarnings = \"-Wall -Wextra\",\nFatalWarnings = \"-Werror\",\nFloatFast = \"-ffast-math\",\nFloatStrict = \"-ffloat-store\",\nNoFramePointer = \"-fomit-frame-pointer\",\nOptimize = \"-O2\",\nOptimizeSize = \"-Os\",\nOptimizeSpeed = \"-O3\",\nSymbols = \"-g\",\n}\nlocal cxxflags =\n{\nCpp11 = \"-std=c++11\",\nCpp14 = \"-std=c++14\",\nCpp17 = \"-std=c++17\",\nCppLatest = \"-std=c++2a\",\nNoExceptions = \"-fno-exceptions\",\nNoRTTI = \"-fno-rtti\",\nUnsignedChar = \"-funsigned-char\",\n}\nlocal objcflags =\n{\nObjcARC = \"-fobjc-arc\",\n}\npremake.gcc.platforms =\n{\nNative = {\n" +- "cppflags = \"-MMD -MP\",\n},\nx32 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m32\",\n},\nx64 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m64\",\n},\nUniversal = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",\n},\nUniversal32 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch ppc\",\n},\nUniversal64 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch x86_64 -arch ppc64\",\n},\nPS3 = {\ncc = \"ppu-lv2-g++\",\ncxx = \"ppu-lv2-g++\",\nar = \"ppu-lv2-ar\",\ncppflags = \"-MMD -MP\",\n},\nWiiDev = {\ncppflags = \"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",\nldflags= \"-L$(LIBOGC_LIB) $(MACHDEP)\",\ncfgsettings = [[\n ifeq ($(strip $(DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],\n},\nOrbis = {\ncc = \"orbis-clang\",\ncxx = \"orbis-clang++\",\nar = \"orbis-ar\",\ncppflag" ++ "cppflags = \"-MMD -MP\",\n},\nx32 = {\ncppflags = \"-MMD -MP\"\n},\nx64 = {\ncppflags = \"-MMD -MP\",\nflags = \"-m64\",\n},\nUniversal = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",\n},\nUniversal32 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch i386 -arch ppc\",\n},\nUniversal64 = {\nar = \"libtool\",\ncppflags = \"-MMD -MP\",\nflags = \"-arch x86_64 -arch ppc64\",\n},\nPS3 = {\ncc = \"ppu-lv2-g++\",\ncxx = \"ppu-lv2-g++\",\nar = \"ppu-lv2-ar\",\ncppflags = \"-MMD -MP\",\n},\nWiiDev = {\ncppflags = \"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",\nldflags= \"-L$(LIBOGC_LIB) $(MACHDEP)\",\ncfgsettings = [[\n ifeq ($(strip $(DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],\n},\nOrbis = {\ncc = \"orbis-clang\",\ncxx = \"orbis-clang++\",\nar = \"orbis-ar\",\ncppflag" + "s = \"-MMD -MP\",\n},\nEmscripten = {\ncc = \"$(EMSCRIPTEN)/emcc\",\ncxx = \"$(EMSCRIPTEN)/em++\",\nar = \"$(EMSCRIPTEN)/emar\",\ncppflags = \"-MMD -MP\",\n}\n}\nlocal platforms = premake.gcc.platforms\nfunction premake.gcc.getcppflags(cfg)\nlocal flags = { }\ntable.insert(flags, platforms[cfg.platform].cppflags)\nif flags[1]:startswith(\"-MMD\") then\ntable.insert(flags, \"-MP\")\nend\nreturn flags\nend\nfunction premake.gcc.getcflags(cfg)\nlocal result = table.translate(cfg.flags, cflags)\ntable.insert(result, platforms[cfg.platform].flags)\nif cfg.system ~= \"windows\" and cfg.kind == \"SharedLib\" then\ntable.insert(result, \"-fPIC\")\nend\nreturn result\nend\nfunction premake.gcc.getcxxflags(cfg)\nlocal result = table.translate(cfg.flags, cxxflags)\nreturn result\nend\nfunction premake.gcc.getobjcflags(cfg)\nreturn table.translate(cfg.flags, objcflags)\nend\nfunction premake.gcc.getldflags(cfg)\nlocal result = { }\nif not cfg.flags.Symbols then\nif cfg.system == \"macosx\" then" + "\nelse\ntable.insert(result, \"-s\")\nend\nend\nif cfg.kind == \"Bundle\" then\ntable.insert(result, \"-bundle\")\nend\nif cfg.kind == \"SharedLib\" then\nif cfg.system == \"macosx\" then\ntable.insert(result, \"-dynamiclib\")\nelse\ntable.insert(result, \"-shared\")\nend\nif cfg.system == \"windows\" and not cfg.flags.NoImportLib then\ntable.insert(result, '-Wl,--out-implib=\"' .. cfg.linktarget.fullpath .. '\"')\nend\nend\nif cfg.kind == \"WindowedApp\" and cfg.system == \"windows\" then\ntable.insert(result, \"-mwindows\")\nend\nlocal platform = platforms[cfg.platform]\ntable.insert(result, platform.flags)\ntable.insert(result, platform.ldflags)\nreturn result\nend\nfunction premake.gcc.getlibdirflags(cfg)\nlocal result = { }\nfor _, value in ipairs(premake.getlinks(cfg, \"all\", \"directory\")) do\ntable.insert(result, '-L\\\"' .. value .. '\\\"')\nend\nreturn result\nend\nfunction premake.gcc.islibfile(p)\nif path.getextension(p) == \".a\" then\nreturn true\nend\nreturn false\nend\nfunction premake.gcc.ge" + "tlibfiles(cfg)\nlocal result = {}\nfor _, value in ipairs(premake.getlinks(cfg, \"system\", \"fullpath\")) do\nif premake.gcc.islibfile(value) then\ntable.insert(result, _MAKE.esc(value))\nend\nend\nreturn result\nend\nfunction premake.gcc.getlinkflags(cfg)\nlocal result = {}\nfor _, value in ipairs(premake.getlinks(cfg, \"system\", \"fullpath\")) do\nif premake.gcc.islibfile(value) then\nvalue = path.rebase(value, cfg.project.location, cfg.location)\ntable.insert(result, _MAKE.esc(value))\nelseif path.getextension(value) == \".framework\" then\ntable.insert(result, '-framework ' .. _MAKE.esc(path.getbasename(value)))\nelse\ntable.insert(result, '-l' .. _MAKE.esc(path.getname(value)))\nend\nend\nreturn result\nend\nfunction premake.gcc.wholearchive(lib)\nif premake.gcc.llvm then\nreturn {\"-force_load\", lib}\nelse\nreturn {\"-Wl,--whole-archive\", lib, \"-Wl,--no-whole-archive\"}\nend\nend\nfunction premake.gcc.getarchiveflags(prj, cfg, ndx)\nlocal result = {}\nif cfg.platform:startswith(\"Universal\") then\n" +--- a/scripts/toolchain.lua 2019-04-30 15:47:21.000000000 +0200 ++++ b/scripts/toolchain.lua 2019-05-21 22:51:48.116148725 +0200 +@@ -698,9 +698,6 @@ + + configuration { "linux-gcc", "x32" } + objdir (_buildDir .. "linux_gcc" .. "/obj") +- buildoptions { +- "-m32", +- } + + configuration { "linux-gcc", "x32", "Release" } + targetdir (_buildDir .. "linux_gcc" .. "/bin/x32/Release") diff --git a/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r33s b/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r33s new file mode 100644 index 0000000000..2c3bddc36e --- /dev/null +++ b/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.r33s @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 3 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 1 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = JELOS +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1034 +controls_a[CONTROL_INDEX_DOWN] = 1035 +controls_a[CONTROL_INDEX_LEFT] = 1036 +controls_a[CONTROL_INDEX_RIGHT] = 1037 +controls_a[CONTROL_INDEX_A] = 100 +controls_a[CONTROL_INDEX_B] = 99 +controls_a[CONTROL_INDEX_X] = 122 +controls_a[CONTROL_INDEX_Y] = 118 +controls_a[CONTROL_INDEX_L] = 113 +controls_a[CONTROL_INDEX_R] = 111 +controls_a[CONTROL_INDEX_START] = 1033 +controls_a[CONTROL_INDEX_SELECT] = 101 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 120 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 112 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 110 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 338 +controls_a[CONTROL_INDEX_UI_DOWN] = 337 +controls_a[CONTROL_INDEX_UI_LEFT] = 336 +controls_a[CONTROL_INDEX_UI_RIGHT] = 335 +controls_a[CONTROL_INDEX_UI_SELECT] = 13 +controls_a[CONTROL_INDEX_UI_BACK] = 8 +controls_a[CONTROL_INDEX_UI_EXIT] = 27 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 331 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 334 +controls_a[CONTROL_INDEX_UI_SWITCH] = 481 +controls_b[CONTROL_INDEX_UP] = 65535 +controls_b[CONTROL_INDEX_DOWN] = 65535 +controls_b[CONTROL_INDEX_LEFT] = 65535 +controls_b[CONTROL_INDEX_RIGHT] = 65535 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 32 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1034 +controls_b[CONTROL_INDEX_UI_DOWN] = 1035 +controls_b[CONTROL_INDEX_UI_LEFT] = 1036 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1037 +controls_b[CONTROL_INDEX_UI_SELECT] = 1033 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 101 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 118 diff --git a/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.rgb20s b/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.rgb20s new file mode 100644 index 0000000000..948b690ea0 --- /dev/null +++ b/packages/emulators/standalone/drastic-sa/config/RK3326/drastic.cfg.rgb20s @@ -0,0 +1,111 @@ +frameskip_type = 2 +frameskip_value = 4 +safe_frameskip = 0 +show_frame_counter = 0 +screen_orientation = 0 +screen_swap = 0 +savestate_number = 0 +fast_forward = 0 +enable_sound = 1 +clock_speed = 0 +threaded_3d = 0 +mirror_touch = 0 +compress_savestates = 1 +savestate_snapshot = 1 +unzip_roms = 0 +preload_roms = 0 +backup_in_savestates = 1 +ignore_gamecard_limit = 0 +frame_interval = 0 +trim_roms = 0 +fix_main_2d_screen = 0 +disable_edge_marking = 0 +interframe_blend = 0 +hires_3d = 0 +use_rtc_custom_time = 0 +rtc_custom_time = 0 +rtc_system_time = 0 +slot2_device_type = 0 +rumble_frames = 3 +firmware.username = Dr DraStic +firmware.language = 1 +firmware.favorite_color = 0 +firmware.birthday_month = 1 +firmware.birthday_day = 1 +enable_cheats = 1 +controls_a[CONTROL_INDEX_UP] = 1032 +controls_a[CONTROL_INDEX_DOWN] = 1033 +controls_a[CONTROL_INDEX_LEFT] = 1034 +controls_a[CONTROL_INDEX_RIGHT] = 1035 +controls_a[CONTROL_INDEX_A] = 1025 +controls_a[CONTROL_INDEX_B] = 1024 +controls_a[CONTROL_INDEX_X] = 1026 +controls_a[CONTROL_INDEX_Y] = 1027 +controls_a[CONTROL_INDEX_L] = 1028 +controls_a[CONTROL_INDEX_R] = 1029 +controls_a[CONTROL_INDEX_START] = 1037 +controls_a[CONTROL_INDEX_SELECT] = 1036 +controls_a[CONTROL_INDEX_HINGE] = 65535 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_UP] = 1219 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 1155 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 1218 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 1154 +controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 1039 +controls_a[CONTROL_INDEX_MENU] = 1038 +controls_a[CONTROL_INDEX_SAVE_STATE] = 1031 +controls_a[CONTROL_INDEX_LOAD_STATE] = 1030 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 110 +controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 112 +controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_a[CONTROL_INDEX_QUIT] = 65535 +controls_a[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_a[CONTROL_INDEX_UI_UP] = 1032 +controls_a[CONTROL_INDEX_UI_DOWN] = 1033 +controls_a[CONTROL_INDEX_UI_LEFT] = 1034 +controls_a[CONTROL_INDEX_UI_RIGHT] = 1035 +controls_a[CONTROL_INDEX_UI_SELECT] = 1025 +controls_a[CONTROL_INDEX_UI_BACK] = 1026 +controls_a[CONTROL_INDEX_UI_EXIT] = 1024 +controls_a[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_a[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_a[CONTROL_INDEX_UI_SWITCH] = 65535 +controls_b[CONTROL_INDEX_UP] = 1217 +controls_b[CONTROL_INDEX_DOWN] = 1153 +controls_b[CONTROL_INDEX_LEFT] = 1216 +controls_b[CONTROL_INDEX_RIGHT] = 1152 +controls_b[CONTROL_INDEX_A] = 65535 +controls_b[CONTROL_INDEX_B] = 65535 +controls_b[CONTROL_INDEX_X] = 65535 +controls_b[CONTROL_INDEX_Y] = 65535 +controls_b[CONTROL_INDEX_L] = 65535 +controls_b[CONTROL_INDEX_R] = 65535 +controls_b[CONTROL_INDEX_START] = 65535 +controls_b[CONTROL_INDEX_SELECT] = 65535 +controls_b[CONTROL_INDEX_HINGE] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_UP] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 +controls_b[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 +controls_b[CONTROL_INDEX_MENU] = 65535 +controls_b[CONTROL_INDEX_SAVE_STATE] = 65535 +controls_b[CONTROL_INDEX_LOAD_STATE] = 65535 +controls_b[CONTROL_INDEX_FAST_FORWARD] = 65535 +controls_b[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 +controls_b[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 +controls_b[CONTROL_INDEX_LOAD_GAME] = 65535 +controls_b[CONTROL_INDEX_QUIT] = 65535 +controls_b[CONTROL_INDEX_FAKE_MICROPHONE] = 65535 +controls_b[CONTROL_INDEX_UI_UP] = 1217 +controls_b[CONTROL_INDEX_UI_DOWN] = 1153 +controls_b[CONTROL_INDEX_UI_LEFT] = 1216 +controls_b[CONTROL_INDEX_UI_RIGHT] = 1152 +controls_b[CONTROL_INDEX_UI_SELECT] = 1037 +controls_b[CONTROL_INDEX_UI_BACK] = 65535 +controls_b[CONTROL_INDEX_UI_EXIT] = 1036 +controls_b[CONTROL_INDEX_UI_PAGE_UP] = 65535 +controls_b[CONTROL_INDEX_UI_PAGE_DOWN] = 65535 +controls_b[CONTROL_INDEX_UI_SWITCH] = 65535 diff --git a/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg b/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg index b101b8db8e..1049e5cb38 100644 --- a/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg +++ b/packages/emulators/standalone/drastic-sa/config/RK3399/drastic.cfg @@ -51,11 +51,11 @@ controls_a[CONTROL_INDEX_TOUCH_CURSOR_DOWN] = 65535 controls_a[CONTROL_INDEX_TOUCH_CURSOR_LEFT] = 65535 controls_a[CONTROL_INDEX_TOUCH_CURSOR_RIGHT] = 65535 controls_a[CONTROL_INDEX_TOUCH_CURSOR_PRESS] = 65535 -controls_a[CONTROL_INDEX_MENU] = 65535 -controls_a[CONTROL_INDEX_SAVE_STATE] = 65535 -controls_a[CONTROL_INDEX_LOAD_STATE] = 65535 -controls_a[CONTROL_INDEX_FAST_FORWARD] = 65535 -controls_a[CONTROL_INDEX_SWAP_SCREENS] = 65535 +controls_a[CONTROL_INDEX_MENU] = 120 +controls_a[CONTROL_INDEX_SAVE_STATE] = 115 +controls_a[CONTROL_INDEX_LOAD_STATE] = 108 +controls_a[CONTROL_INDEX_FAST_FORWARD] = 116 +controls_a[CONTROL_INDEX_SWAP_SCREENS] = 109 controls_a[CONTROL_INDEX_SWAP_ORIENTATION_A] = 65535 controls_a[CONTROL_INDEX_SWAP_ORIENTATION_B] = 65535 controls_a[CONTROL_INDEX_LOAD_GAME] = 65535 diff --git a/packages/emulators/standalone/drastic-sa/config/drastic.gptk b/packages/emulators/standalone/drastic-sa/config/drastic.gptk new file mode 100644 index 0000000000..036a3b08b7 --- /dev/null +++ b/packages/emulators/standalone/drastic-sa/config/drastic.gptk @@ -0,0 +1,32 @@ +ack = e +start = \\ +a = d +a_hk = a +b = c +b_hk = b +x = z +x_hk = x +y = v +y_hk = y +l1 = q +l1_hk = l +l2 = n +l2_hk = m +l3 = \\ +r1 = o +r1_hk = s +r2 = p +r2_hk = t +r3 = \\ +up = \\ +down = \\ +left = \\ +right = \\ +left_analog_up = \\ +left_analog_down = \\ +left_analog_left = \\ +left_analog_right = \\ +right_analog_up = \\ +right_analog_down = \\ +right_analog_left = \\ +right_analog_right = \\ diff --git a/packages/emulators/standalone/drastic-sa/package.mk b/packages/emulators/standalone/drastic-sa/package.mk index e79ecc3854..ad5f2a187c 100644 --- a/packages/emulators/standalone/drastic-sa/package.mk +++ b/packages/emulators/standalone/drastic-sa/package.mk @@ -26,6 +26,7 @@ makeinstall_target() { mkdir -p ${INSTALL}/usr/config/drastic/config cp -rf ${PKG_BUILD}/drastic_aarch64/* ${INSTALL}/usr/config/drastic/ cp -rf ${PKG_DIR}/config/${DEVICE}/* ${INSTALL}/usr/config/drastic/config/ + cp -rf ${PKG_DIR}/config/drastic.gptk ${INSTALL}/usr/config/drastic/ } post_install() { diff --git a/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh b/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh index 6a77d2cb6c..ec4b5c9a8f 100644 --- a/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh +++ b/packages/emulators/standalone/drastic-sa/scripts/start_drastic.sh @@ -7,6 +7,11 @@ jslisten set "-9 drastic" +#load gptokeyb support files +control-gen_init.sh +source /storage/.config/gptokeyb/control.ini +get_controls + #Copy drastic files to .config if [ ! -d "/storage/.config/drastic" ]; then mkdir -p /storage/.config/drastic/ @@ -14,7 +19,7 @@ if [ ! -d "/storage/.config/drastic" ]; then fi if [ ! -d "/storage/.config/drastic/system" ]; then - mkdir -p mkdir -p /storage/.config/drastic/system + mkdir -p /storage/.config/drastic/system fi for bios in nds_bios_arm9.bin nds_bios_arm7.bin @@ -26,6 +31,11 @@ do fi done +#Copy drastic files to .config +if [ ! -f "/storage/.config/drastic/drastic.gptk" ]; then + cp -r /usr/config/drastic/drastic.gptk /storage/.config/drastic/ +fi + #Make drastic savestate folder if [ ! -d "/storage/roms/savestates/nds" ]; then mkdir -p /storage/roms/savestates/nds @@ -41,4 +51,6 @@ ln -sf /storage/roms/nds /storage/.config/drastic/backup cd /storage/.config/drastic/ @LIBEGL@ +$GPTOKEYB "drastic" -c "drastic.gptk" & ./drastic "$1" +kill -9 $(pidof gptokeyb) diff --git a/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_r33s_joypad.cfg b/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_r33s_joypad.cfg new file mode 100644 index 0000000000..abd5b1c153 --- /dev/null +++ b/packages/emulators/standalone/flycast-sa/config/RK3326/mappings/SDL_r33s_joypad.cfg @@ -0,0 +1,21 @@ +[digital] +bind0 = 0:btn_a +bind1 = 1:btn_b +bind10 = 10:btn_analog_up +bind11 = 11:btn_analog_down +bind12 = 12:btn_analog_left +bind13 = 13:btn_analog_right +bind2 = 2:btn_y +bind3 = 3:btn_x +bind4 = 4:btn_trigger_left +bind5 = 5:btn_trigger_right +bind6 = 6:btn_jump_state +bind7 = 7:btn_quick_save +bind8 = 8:btn_menu +bind9 = 9:btn_start + +[emulator] +dead_zone = 10 +mapping_name = r33s_joypad +rumble_power = 100 +version = 3 diff --git a/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.r33s b/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.r33s new file mode 100644 index 0000000000..7cb37f90f9 --- /dev/null +++ b/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.r33s @@ -0,0 +1,670 @@ +# Mupen64Plus Configuration File +# This file is automatically read and written by the Mupen64Plus Core library + +[64DD] + +# Filename of the 64DD IPL ROM +IPL-ROM = "" +# Filename of the disk to load into Disk Drive +Disk = "" + + +[Audio-SDL] + +# Mupen64Plus SDL Audio Plugin config parameter version number +Version = 1.000000 +# Frequency which is used if rom doesn't want to change it +DEFAULT_FREQUENCY = 33600 +# Swaps left and right channels +SWAP_CHANNELS = False +# Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory. +PRIMARY_BUFFER_SIZE = 16384 +# Fullness level target for Primary audio buffer, in equivalent output samples. This value must be larger than the SECONDARY_BUFFER_SIZE. Decreasing this value will reduce audio latency but requires a faster PC to avoid choppiness. Increasing this will increase audio latency but reduce the chance of drop-outs. +PRIMARY_BUFFER_TARGET = 2048 +# Size of secondary buffer in output samples. This is SDL's hardware buffer. The SDL documentation states that this should be a power of two between 512 and 8192. +SECONDARY_BUFFER_SIZE = 1024 +# Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial +RESAMPLE = "trivial" +# Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume) +VOLUME_CONTROL_TYPE = 1 +# Percentage change each time the volume is increased or decreased +VOLUME_ADJUST = 5 +# Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1 +VOLUME_DEFAULT = 100 +# Synchronize Video/Audio +AUDIO_SYNC = False + + +[Core] + +# Mupen64Plus Core config parameter set version number. Please don't change this version number. +Version = 1.010000 +# Draw on-screen display if True, otherwise don't draw OSD +OnScreenDisplay = True +# Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more +R4300Emulator = 2 +# Disable compiled jump commands in dynamic recompiler (should be set to False) +NoCompiledJump = False +# Disable 4MB expansion RAM pack. May be necessary for some games +DisableExtraMem = False +# Increment the save state slot after each save operation +AutoStateSlotIncrement = False +# Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support +EnableDebugger = False +# Save state slot (0-9) to use when saving/loading the emulator state +CurrentStateSlot = 0 +# Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used +ScreenshotPath = "/storage/roms/n64" +# Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used +SaveStatePath = "/storage/roms/n64" +# Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used +SaveSRAMPath = "/storage/roms/n64" +# Path to a directory to search when looking for shared data files +SharedDataPath = "/tmp/mupen64plussa" +# Force number of cycles per emulated instruction +CountPerOp = 0 +# Randomize PI/SI Interrupt Timing +RandomizeInterrupt = True +# Duration of SI DMA (-1: use per game settings) +SiDmaDuration = -1 +# Gameboy Camera Video Capture backend +GbCameraVideoCaptureBackend1 = "" +# Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram)) +SaveDiskFormat = 1 + + +[CoreEvents] + +# Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number. +Version = 1.000000 +# SDL keysym for stopping the emulator +Kbd Mapping Stop = 27 +# SDL keysym for switching between fullscreen/windowed modes +Kbd Mapping Fullscreen = 0 +# SDL keysym for saving the emulator state +Kbd Mapping Save State = 286 +# SDL keysym for loading the emulator state +Kbd Mapping Load State = 288 +# SDL keysym for advancing the save state slot +Kbd Mapping Increment Slot = 0 +# SDL keysym for resetting the emulator +Kbd Mapping Reset = 290 +# SDL keysym for slowing down the emulator +Kbd Mapping Speed Down = 291 +# SDL keysym for speeding up the emulator +Kbd Mapping Speed Up = 292 +# SDL keysym for taking a screenshot +Kbd Mapping Screenshot = 293 +# SDL keysym for pausing the emulator +Kbd Mapping Pause = 112 +# SDL keysym for muting/unmuting the sound +Kbd Mapping Mute = 109 +# SDL keysym for increasing the volume +Kbd Mapping Increase Volume = 93 +# SDL keysym for decreasing the volume +Kbd Mapping Decrease Volume = 91 +# SDL keysym for temporarily going really fast +Kbd Mapping Fast Forward = 102 +# SDL keysym for advancing by one frame when paused +Kbd Mapping Frame Advance = 47 +# SDL keysym for pressing the game shark button +Kbd Mapping Gameshark = 103 +# Joystick event string for stopping the emulator +Joy Mapping Stop = "J0B8/B9" +# Joystick event string for switching between fullscreen/windowed modes +Joy Mapping Fullscreen = "" +# Joystick event string for saving the emulator state +Joy Mapping Save State = "J0B8/B5" +# Joystick event string for loading the emulator state +Joy Mapping Load State = "J0B8/B4" +# Joystick event string for advancing the save state slot +Joy Mapping Increment Slot = "" +# Joystick event string for resetting the emulator +Joy Mapping Reset = "" +# Joystick event string for slowing down the emulator +Joy Mapping Speed Down = "" +# Joystick event string for speeding up the emulator +Joy Mapping Speed Up = "" +# Joystick event string for taking a screenshot +Joy Mapping Screenshot = "" +# Joystick event string for pausing the emulator +Joy Mapping Pause = "J0B8/B0" +# Joystick event string for muting/unmuting the sound +Joy Mapping Mute = "" +# Joystick event string for increasing the volume +Joy Mapping Increase Volume = "" +# Joystick event string for decreasing the volume +Joy Mapping Decrease Volume = "" +# Joystick event string for fast-forward +Joy Mapping Fast Forward = "J0B8/B7" +# Joystick event string for advancing by one frame when paused +Joy Mapping Frame Advance = "" +# Joystick event string for pressing the game shark button +Joy Mapping Gameshark = "" +# SDL keysym for save slot 0 +Kbd Mapping Slot 0 = 48 +# SDL keysym for save slot 1 +Kbd Mapping Slot 1 = 49 +# SDL keysym for save slot 2 +Kbd Mapping Slot 2 = 50 +# SDL keysym for save slot 3 +Kbd Mapping Slot 3 = 51 +# SDL keysym for save slot 4 +Kbd Mapping Slot 4 = 52 +# SDL keysym for save slot 5 +Kbd Mapping Slot 5 = 53 +# SDL keysym for save slot 6 +Kbd Mapping Slot 6 = 54 +# SDL keysym for save slot 7 +Kbd Mapping Slot 7 = 55 +# SDL keysym for save slot 8 +Kbd Mapping Slot 8 = 56 +# SDL keysym for save slot 9 +Kbd Mapping Slot 9 = 57 + + +[Input-SDL-Control1] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = 0 +# SDL joystick name (or Keyboard) +name = "r33s_joypad" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = True +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "0,0" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(7) +C Button L = button(6) +C Button D = button(1) +C Button U = button(2) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = button(12,13)axis(0-,0+) +Y Axis = butoon(10,11)axis(1-,1+) + +[Input-SDL-Control2] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control3] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Input-SDL-Control4] + +# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number. +version = 2.000000 +# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic +mode = 2 +# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number +device = -1 +# SDL joystick name (or Keyboard) +name = "" +# Specifies whether this controller is 'plugged in' to the simulated N64 +plugged = False +# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak +plugin = 2 +# If True, then mouse buttons may be used with this controller +mouse = False +# Scaling factor for mouse movements. For X, Y axes. +MouseSensitivity = "2.00,2.00" +# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes. +AnalogDeadzone = "4096,4096" +# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value +AnalogPeak = "32768,32768" +# Digital button configuration mappings +DPad R = "" +DPad L = "" +DPad D = "" +DPad U = "" +Start = "" +Z Trig = "" +B Button = "" +A Button = "" +C Button R = "" +C Button L = "" +C Button D = "" +C Button U = "" +R Trig = "" +L Trig = "" +Mempak switch = "" +Rumblepak switch = "" +# Analog axis configuration mappings +X Axis = "" +Y Axis = "" + + +[Rsp-HLE] + +# Mupen64Plus RSP HLE Plugin config parameter version number +Version = 1.000000 +# Path to a RSP plugin which will be used when encountering an unknown ucode.You can disable this by letting an empty string. +RspFallback = "" +# Send display lists to the graphics plugin +DisplayListToGraphicsPlugin = True +# Send audio lists to the audio plugin +AudioListToAudioPlugin = False + + +[Transferpak] + +# Filename of the GB ROM to load into transferpak 1 +GB-rom-1 = "" +# Filename of the GB RAM to load into transferpak 1 +GB-ram-1 = "" +# Filename of the GB ROM to load into transferpak 2 +GB-rom-2 = "" +# Filename of the GB RAM to load into transferpak 2 +GB-ram-2 = "" +# Filename of the GB ROM to load into transferpak 3 +GB-rom-3 = "" +# Filename of the GB RAM to load into transferpak 3 +GB-ram-3 = "" +# Filename of the GB ROM to load into transferpak 4 +GB-rom-4 = "" +# Filename of the GB RAM to load into transferpak 4 +GB-ram-4 = "" + + +[UI-Console] + +# Mupen64Plus UI-Console config parameter set version number. Please don't change this version number. +Version = 1.000000 +# Directory in which to search for plugins +PluginDir = "/usr/local/lib/mupen64plus" +# Filename of video plugin +VideoPlugin = "mupen64plus-video-rice" +# Filename of audio plugin +AudioPlugin = "mupen64plus-audio-sdl.so" +# Filename of input plugin +InputPlugin = "mupen64plus-input-sdl.so" +# Filename of RSP plugin +RspPlugin = "mupen64plus-rsp-hle.so" + + +[Video-General] + +# Width of output window or fullscreen width +ScreenWidth = 427 +# Height of output window or fullscreen height +ScreenHeight = 320 +# Use fullscreen mode if True, or windowed mode if False +Fullscreen = True +# If true, activate the SDL_GL_SWAP_CONTROL attribute +VerticalSync = True +# Rotate screen contents: 0=0 degree, 1=90 degree, 2 = 180 degree, 3=270 degree +Rotate = 0 + +[Video-GLideN64] + +###### Hardware Compatibility ###### +# Leave enabled unless a mobile gpu doesn't support it. +EnableFragmentDepthWrite = 1 +# Hardware per pixel lighting, supposedly good for GLES3.1 devices or higher. +EnableHWLighting = 0 + +###### Enhancements ####### +# Internal render resoluton rather than output. So 2 x 240p is 480p, etc. +UseNativeResolutionFactor = 1 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Enable/Disable Fast Approximate Anti-Aliasing FXAA +FXAA = 0 +# Max level of Anisotropic Filtering, 0 for off +anisotropy = 0 +# Bilinear filtering mode (0=N64 3point, 1=standard) +# @rishooty: best to use this at 1x native res, any higher turn it off. +bilinearMode = 1 + +###### Compatibility ###### +# Make texrect coordinates continuous to avoid black lines between them. (0=Off/default, 1=Auto, 2=Force) +CorrectTexrectCoords = 1 +# Copy auxiliary buffers to RDRAM (default: 0) +EnableCopyAuxiliaryToRDRAM = 1 +# Render 2D texrects in native resolution to fix misalignment between parts of 2D image. (0=Off/default, 1=Optimized, 2=Unoptimized)") +EnableNativeResTexrects = 1 + +###### Other ###### +# Enable threaded video backend at the cost of input lag +ThreadedVideo = 1 +# Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust) +AspectRatio = 1 +# Display On-screen FPS +ShowFPS = False + +[Video-Glide64mk2] + +# Enable full-scene anti-aliasing by setting this to a value greater than 1 +wrpAntiAliasing = 0 +# Card ID +card_id = 0 +# If true, use polygon offset values specified below +force_polygon_offset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +polygon_offset_factor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +polygon_offset_units = 0.000000 +# Vertical sync +vsync = True +# TODO:ssformat +ssformat = False +# Display performance stats (add together desired flags): 1=FPS counter, 2=VI/s counter, 4=% speed, 8=FPS transparent +show_fps = 0 +# Clock enabled +clock = False +# Clock is 24-hour +clock_24_hr = True +# Wrapper resolution +wrpResolution = 0 +# Wrapper VRAM +wrpVRAM = 0 +# Wrapper FBO +wrpFBO = True +# Wrapper Anisotropic Filtering +wrpAnisotropic = True +# Texture Enhancement: Smooth/Sharpen Filters +ghq_fltr = 0 +# Texture Compression: 0 for S3TC, 1 for FXT1 +ghq_cmpr = 0 +# Texture Enhancement: More filters +ghq_enht = 0 +# Hi-res texture pack format (0 for none, 1 for Rice) +ghq_hirs = 1 +# Compress texture cache with S3TC or FXT1 +ghq_enht_cmpr = False +# Tile textures (saves memory but could cause issues) +ghq_enht_tile = 0 +# Force 16bpp textures (saves ram but lower quality) +ghq_enht_f16bpp = False +# Compress texture cache +ghq_enht_gz = True +# Don't enhance textures for backgrounds +ghq_enht_nobg = False +# Enable S3TC and FXT1 compression +ghq_hirs_cmpr = False +# Tile hi-res textures (saves memory but could cause issues) +ghq_hirs_tile = False +# Force 16bpp hi-res textures (saves ram but lower quality) +ghq_hirs_f16bpp = False +# Compress hi-res texture cache +ghq_hirs_gz = True +# Alternative CRC calculation -- emulates Rice bug +ghq_hirs_altcrc = True +# Save tex cache to disk +ghq_cache_save = True +# Texture Cache Size (MB) +ghq_cache_size = 128 +# Use full alpha channel -- could cause issues for some tex packs +ghq_hirs_let_texartists_fly = False +# Dump textures +ghq_hirs_dump = False +# Alternate texture size method: -1=Game default, 0=disable. 1=enable +alt_tex_size = -1 +# Use first SETTILESIZE only: -1=Game default, 0=disable. 1=enable +use_sts1_only = -1 +# Use spheric mapping only: -1=Game default, 0=disable. 1=enable +force_calc_sphere = -1 +# Force positive viewport: -1=Game default, 0=disable. 1=enable +correct_viewport = -1 +# Force texrect size to integral value: -1=Game default, 0=disable. 1=enable +increase_texrect_edge = -1 +# Reduce fillrect size by 1: -1=Game default, 0=disable. 1=enable +decrease_fillrect_edge = -1 +# Enable perspective texture correction emulation: -1=Game default, 0=disable. 1=enable +texture_correction = -1 +# Set special scale for PAL games: -1=Game default, 0=disable. 1=enable +pal230 = -1 +# 3DFX Dithered alpha emulation mode: -1=Game default, >=0=dithered alpha emulation mode +stipple_mode = -1 +# 3DFX Dithered alpha pattern: -1=Game default, >=0=pattern used for dithered alpha emulation +stipple_pattern = -1 +# Check microcode each frame: -1=Game default, 0=disable. 1=enable +force_microcheck = -1 +# Force 0xb5 command to be quad, not line 3D: -1=Game default, 0=disable. 1=enable +force_quad3d = -1 +# Enable near z clipping: -1=Game default, 0=disable. 1=enable +clip_zmin = -1 +# Enable far plane clipping: -1=Game default, 0=disable. 1=enable +clip_zmax = -1 +# Use fast CRC algorithm: -1=Game default, 0=disable. 1=enable +fast_crc = -1 +# Adjust screen aspect for wide screen mode: -1=Game default, 0=disable. 1=enable +adjust_aspect = -1 +# Force strict check in Depth buffer test: -1=Game default, 0=disable. 1=enable +zmode_compare_less = -1 +# Apply alpha dither regardless of alpha_dither_mode: -1=Game default, 0=disable. 1=enable +old_style_adither = -1 +# Scale vertex z value before writing to depth buffer: -1=Game default, 0=disable. 1=enable +n64_z_scale = -1 +# Fast texrect rendering with hwfbe: -1=Game default, 0=disable. 1=enable +optimize_texrect = -1 +# Do not copy auxiliary frame buffers: -1=Game default, 0=disable. 1=enable +ignore_aux_copy = -1 +# Clear auxiliary texture frame buffers: -1=Game default, 0=disable. 1=enable +hires_buf_clear = -1 +# Read alpha from framebuffer: -1=Game default, 0=disable. 1=enable +fb_read_alpha = -1 +# Handle unchanged fb: -1=Game default, 0=disable. 1=enable +useless_is_useless = -1 +# Set frambuffer CRC mode: -1=Game default, 0=disable CRC, 1=fast CRC, 2=safe CRC +fb_crc_mode = -1 +# Filtering mode: -1=Game default, 0=automatic, 1=force bilinear, 2=force point sampled +filtering = -1 +# Fog: -1=Game default, 0=disable. 1=enable +fog = -1 +# Buffer clear on every frame: -1=Game default, 0=disable. 1=enable +buff_clear = -1 +# Buffer swapping method: -1=Game default, 0=swap buffers when vertical interrupt has occurred, 1=swap buffers when set of conditions is satisfied. Prevents flicker on some games, 2=mix of first two methods +swapmode = -1 +# Aspect ratio: -1=Game default, 0=Force 4:3, 1=Force 16:9, 2=Stretch, 3=Original +aspect = -1 +# LOD calculation: -1=Game default, 0=disable. 1=fast, 2=precise +lodmode = -1 +# Smart framebuffer: -1=Game default, 0=disable. 1=enable +fb_smart = -1 +# Hardware frame buffer emulation: -1=Game default, 0=disable. 1=enable +fb_hires = -1 +# Read framebuffer every frame (may be slow use only for effects that need it e.g. Banjo Kazooie, DK64 transitions): -1=Game default, 0=disable. 1=enable +fb_read_always = -1 +# Render N64 frame buffer as texture: -1=Game default, 0=disable, 1=mode1, 2=mode2 +read_back_to_screen = -1 +# Show images written directly by CPU: -1=Game default, 0=disable. 1=enable +detect_cpu_write = -1 +# Get frame buffer info: -1=Game default, 0=disable. 1=enable +fb_get_info = -1 +# Enable software depth render: -1=Game default, 0=disable. 1=enable +fb_render = -1 +# If true, skip up to maxframeskip frames to maintain clock schedule; if false, skip exactly maxframeskip frames +autoframeskip = False +# If autoframeskip is true, skip up to this many frames to maintain clock schedule; if autoframeskip is false, skip exactly this many frames +maxframeskip = 0 + + +[Video-Rice] + +# Hack to accomodate widescreen devices +ResolutionWidth = 480 +# Mupen64Plus Rice Video Plugin config parameter version number +Version = 1 +# Frame Buffer Emulation (0=ROM default, 1=disable) +FrameBufferSetting = 0 +# Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc) +FrameBufferWriteBackControl = 0 +# Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload) +RenderToTexture = 0 +# Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn) +ScreenUpdateSetting = 4 +# Force to use normal alpha blender +NormalAlphaBlender = False +# Use a faster algorithm to speed up texture loading and CRC computation +FastTextureLoading = False +# Use different texture coordinate clamping code +AccurateTextureMapping = True +# Force emulated frame buffers to be in N64 native resolution +InN64Resolution = False +# Try to reduce Video RAM usage (should never be used) +SaveVRAM = False +# Enable this option to have better render-to-texture quality +DoubleSizeForSmallTxtrBuf = False +# Force to use normal color combiner +DefaultCombinerDisable = False +# Enable game-specific settings from INI file +EnableHacks = True +# If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode +WinFrameMode = False +# N64 Texture Memory Full Emulation (may fix some games, may break others) +FullTMEMEmulation = False +# Enable vertex clipper for fog operations +OpenGLVertexClipper = False +# Enable/Disable SSE optimizations for capable CPUs +EnableSSE = True +# If this option is enabled, the plugin will skip every other frame +SkipFrame = False +# If enabled, texture enhancement will be done only for TxtRect ucode +TexRectOnly = False +# If enabled, texture enhancement will be done only for textures width+height<=128 +SmallTextureOnly = False +# Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility) +LoadHiResCRCOnly = True +# Enable hi-resolution texture file loading +LoadHiResTextures = False +# Enable texture dumping +DumpTexturesToFiles = False +# Display On-screen FPS +ShowFPS = False +# Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear +Mipmapping = 2 +# Enable, Disable fog generation (0=Disable, 1=Enable) +FogMethod = 1 +# Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering) +ForceTextureFilter = 0 +# Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored) +TextureEnhancement = 0 +# Secondary texture enhancement filter (0 = none, 1-4 = filtered) +TextureEnhancementControl = 0 +# Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits) +TextureQuality = 0 +# Z-buffer depth (only 16 or 32) +OpenGLDepthBufferSetting = 16 +# Enable/Disable MultiSampling (0=off, 2,4,8,16=quality) +MultiSampling = 0 +# Color bit depth for rendering window (0=32 bits, 1=16 bits) +ColorQuality = 1 +# OpenGL level to support (0=auto, 1=OGL_FRAGMENT_PROGRAM) +OpenGLRenderSetting = 0 +# Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering +AnisotropicFiltering = 0 +# If true, use polygon offset values specified below +ForcePolygonOffset = False +# Specifies a scale factor that is used to create a variable depth offset for each polygon +PolygonOffsetFactor = 0.000000 +# Is multiplied by an implementation-specific value to create a constant depth offset +PolygonOffsetUnits = 0.000000 diff --git a/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut b/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut index f8330414b8..edf332ab36 100644 --- a/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut +++ b/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-core/config/RK3326/mupen64plus.cfg.xut @@ -172,7 +172,7 @@ mode = 2 # Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number device = 0 # SDL joystick name (or Keyboard) -name = "xu10_joypad" +name = "XU10 Gamepad" # Specifies whether this controller is 'plugged in' to the simulated N64 plugged = True # Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak @@ -195,15 +195,15 @@ DPad L = button(14) DPad D = button(13) DPad U = button(12) Start = button(9) -Z Trig = button(4) -B Button = button(3) -A Button = button(0) +Z Trig = button(7) +B Button = button(1) +A Button = button(2) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) -L Trig = button(6) +L Trig = button(4) Mempak switch = Rumblepak switch = # Analog axis configuration mappings diff --git a/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini b/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini index 286014eeb2..e03cfdde70 100644 --- a/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini +++ b/packages/emulators/standalone/mupen64plus-sa/mupen64plus-sa-input-sdl/config/RK3326/default.ini @@ -98,3 +98,53 @@ Rumblepak switch = # Analog axis configuration mappings X Axis = axis(0-,0+) Y Axis = axis(1-,1+) + +[r33s_joypad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768,32768 +DPad R = +DPad L = +DPad D = +DPad U = +Start = button(9) +Z Trig = button(4) +B Button = button(3) +A Button = button(0) +C Button R = button(7) +C Button L = button(6) +C Button D = button(1) +C Button U = button(2) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +# Analog axis configuration mappings +X Axis = button(12,13)axis(0-,0+) +Y Axis = button(10,11)axis(1-,1+) + +[XU10 Gamepad] +plugged = True +mouse = False +AnalogDeadzone = 0,0 +AnalogPeak = 32768, 32768 +DPad R = button(15) +DPad L = button(14) +DPad D = button(13) +DPad U = button(12) +Start = button(9) +Z Trig = button(7) +B Button = button(1) +A Button = button(2) +C Button R = axis(2+) +C Button L = axis(2-) +C Button D = axis(3+) +C Button U = axis(3-) +R Trig = button(5) +L Trig = button(4) +Mempak switch = +Rumblepak switch = +#Analog axis configuration mappings +X Axis = axis(0-,0+) +Y Axis = axis(1-,1+) diff --git a/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 b/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 index c6f8e80971..9185251a60 100755 --- a/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 +++ b/packages/emulators/standalone/pico-8/sources/autostart/common/010-pico8 @@ -3,7 +3,7 @@ # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) PICO_DIR="/storage/roms/pico-8" -if [ -d "${PICO_DIR}" ] +if [ -d "${PICO_DIR}" ] && [ ! -f "${PICO_DIR}/.disable_splore" ] then touch "${PICO_DIR}/Splore.png" fi diff --git a/packages/emulators/standalone/retroarch/package.mk b/packages/emulators/standalone/retroarch/package.mk index eca78abf58..487d8fd95c 100644 --- a/packages/emulators/standalone/retroarch/package.mk +++ b/packages/emulators/standalone/retroarch/package.mk @@ -38,7 +38,7 @@ case ${PROJECT} in esac case ${DEVICE} in - RK3566-X55) + RK3566*) PKG_DEPENDS_TARGET+=" libgo2" PKG_CONFIGURE_OPTS_TARGET+=" --enable-odroidgo2" ;; diff --git a/packages/emulators/standalone/retroarch/patches/0007-xkb-fix.patch b/packages/emulators/standalone/retroarch/patches/0007-xkb-fix.patch deleted file mode 100644 index 630547b0eb..0000000000 --- a/packages/emulators/standalone/retroarch/patches/0007-xkb-fix.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c -index bcdacb60a6..d2f00114bd 100644 ---- a/input/drivers/udev_input.c -+++ b/input/drivers/udev_input.c -@@ -76,14 +76,14 @@ - #include "../../retroarch.h" - #include "../../verbosity.h" - --#if defined(HAVE_XKBCOMMON) && defined(HAVE_KMS) -+#if defined(HAVE_XKBCOMMON) - #define UDEV_XKB_HANDLING - #endif - - /* Force UDEV_XKB_HANDLING for Lakka */ - #ifdef HAVE_LAKKA - #ifndef UDEV_XKB_HANDLING --#define UDEV_XKB_HANDLING -+#undef UDEV_XKB_HANDLING - #endif - #endif - -@@ -1402,7 +1402,7 @@ - /* Force xkb_handling on Lakka */ - udev->xkb_handling = true; - #else -- udev->xkb_handling = string_is_equal(ctx_ident.ident, "kms"); -+ udev->xkb_handling = true; //string_is_equal(ctx_ident.ident, "kms"); - #endif /* HAVE_LAKKA */ - #endif - diff --git a/packages/emulators/standalone/retroarch/patches/RK3566/0011-librga.patch b/packages/emulators/standalone/retroarch/patches/RK3566/0011-librga.patch new file mode 100644 index 0000000000..7f875aea19 --- /dev/null +++ b/packages/emulators/standalone/retroarch/patches/RK3566/0011-librga.patch @@ -0,0 +1,12 @@ +diff -rupN retroarch.orig/gfx/drivers/oga_gfx.c retroarch/gfx/drivers/oga_gfx.c +--- retroarch.orig/gfx/drivers/oga_gfx.c 2022-02-28 19:40:46.222185295 -0500 ++++ retroarch/gfx/drivers/oga_gfx.c 2022-02-28 19:44:14.187909576 -0500 +@@ -22,7 +22,7 @@ + #include "../../verbosity.h" + #include + #include +-#include ++#include + #include + #include + #include diff --git a/packages/emulators/standalone/retroarch/patches/RK3566/002-display-tweaks.patch b/packages/emulators/standalone/retroarch/patches/RK3566/002-display-tweaks.patch new file mode 100644 index 0000000000..bc388cce96 --- /dev/null +++ b/packages/emulators/standalone/retroarch/patches/RK3566/002-display-tweaks.patch @@ -0,0 +1,35 @@ +Correct DRM format on Powkiddy x55, extracted from PowKiddy x55 sources. +diff --git a/deps/libgo2/src/display.c b/deps/libgo2/src/display.c +index b91cf0624b..936b677fc4 100644 +--- a/deps/libgo2/src/display.c ++++ b/deps/libgo2/src/display.c +@@ -550,7 +550,7 @@ static uint32_t go2_rkformat_get(uint32_t drm_fourcc) + + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB8888: +- return RK_FORMAT_BGRA_8888; ++ return RK_FORMAT_RGBA_8888; + + case DRM_FORMAT_RGB565: + return RK_FORMAT_RGB_565; +@@ -586,6 +586,7 @@ void go2_surface_blit(go2_surface_t* srcSurface, int srcX, int srcY, int srcWidt + dst.rect.hstride = dstSurface->height; + dst.rect.format = go2_rkformat_get(dstSurface->format); + ++ + rga_info_t src = { 0 }; + src.fd = go2_surface_prime_fd(srcSurface); + src.mmuFlag = 1; +diff --git a/gfx/drivers_context/drm_go2_ctx.c b/gfx/drivers_context/drm_go2_ctx.c +index b758137703..dbcb992279 100644 +--- a/gfx/drivers_context/drm_go2_ctx.c ++++ b/gfx/drivers_context/drm_go2_ctx.c +@@ -133,7 +133,7 @@ static void *gfx_ctx_go2_drm_init(void *video_driver) + } + + drm->presenter = go2_presenter_create(drm->display, +- DRM_FORMAT_RGB565, 0xff000000, true); ++ DRM_FORMAT_XRGB8888, 0xff000000, true); + + return drm; + } diff --git a/packages/emulators/standalone/retroarch/patches/RK3566/003-fix-go2-rotation.patch b/packages/emulators/standalone/retroarch/patches/RK3566/003-fix-go2-rotation.patch new file mode 100644 index 0000000000..1adb62ad50 --- /dev/null +++ b/packages/emulators/standalone/retroarch/patches/RK3566/003-fix-go2-rotation.patch @@ -0,0 +1,13 @@ +diff --git a/gfx/drivers_context/drm_go2_ctx.c b/gfx/drivers_context/drm_go2_ctx.c +index 856aa0f9a2..baa0ca723a 100644 +--- a/gfx/drivers_context/drm_go2_ctx.c ++++ b/gfx/drivers_context/drm_go2_ctx.c +@@ -122,7 +122,7 @@ static void *gfx_ctx_go2_drm_init(void *video_driver) + drm->native_height = go2_display_width_get(drm->display); + + /* This driver should only be used on rotated screens */ +- if (drm->native_width < drm->native_height) ++ if (drm->native_width <= drm->native_height) + { + /* This should be fixed by using wayland/weston... */ + go2_display_destroy(drm->display); diff --git a/packages/emulators/tools/gamecontrollerdb/config/gamecontrollerdb.txt b/packages/emulators/tools/gamecontrollerdb/config/gamecontrollerdb.txt index 69b7749d4a..dcd836cdb7 100644 --- a/packages/emulators/tools/gamecontrollerdb/config/gamecontrollerdb.txt +++ b/packages/emulators/tools/gamecontrollerdb/config/gamecontrollerdb.txt @@ -7,3 +7,5 @@ 19009b4d4b4800000111000000020000,retrogame_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, 19009b4d4b4800000111000000010000,retrogame_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, 19009321b0c300000002000010000000,XU10 Gamepad,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b16,start:b9,dpleft:b14,dpdown:b13,dpright:b15,dpup:b12,leftshoulder:b4,lefttrigger:b7,rightshoulder:b5,righttrigger:b6,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +190014b3010000009178000000050000,r33s_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b12,dpdown:b11,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7, +1900e5914b4800007711000077010000,RGB20S Gamepad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b12,start:b13,dpleft:b10,dpdown:b9,dpright:b11,dpup:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b14,rightstick:b15,leftx:a0,lefty:a1,rightx:a2,righty:a3, diff --git a/packages/emulators/tools/gptokeyb/package.mk b/packages/emulators/tools/gptokeyb/package.mk index c99e182258..f349141fea 100644 --- a/packages/emulators/tools/gptokeyb/package.mk +++ b/packages/emulators/tools/gptokeyb/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2021-present Shanti Gilbert (https://github.com/shantigilbert) PKG_NAME="gptokeyb" -PKG_VERSION="be8478deed8552293f5ae66cbcf415d23de9be0f" +PKG_VERSION="0303b36b5376a9b25cf82a53ed4242509daf14e9" PKG_ARCH="any" PKG_LICENSE="GPLv3" PKG_SITE="https://github.com/EmuELEC/gptokeyb" diff --git a/packages/emulators/tools/retroarch-joypads/gamepads/RGB20S Gamepad.cfg b/packages/emulators/tools/retroarch-joypads/gamepads/RGB20S Gamepad.cfg new file mode 100644 index 0000000000..3b09cd61f7 --- /dev/null +++ b/packages/emulators/tools/retroarch-joypads/gamepads/RGB20S Gamepad.cfg @@ -0,0 +1,44 @@ +input_driver = "udev" +input_device = "RGB20S Gamepad" +input_device_display_name = "RGB20S Gamepad" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "12" +input_start_btn = "13" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "14" +input_r3_btn = "15" + +input_up_btn = "8" +input_down_btn = "9" +input_left_btn = "10" +input_right_btn = "11" + +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" + +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + +# Hotkeys +input_enable_hotkey_btn = "12" +input_exit_emulator_btn = "13" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/packages/emulators/tools/retroarch-joypads/gamepads/r33s_joypad.cfg b/packages/emulators/tools/retroarch-joypads/gamepads/r33s_joypad.cfg new file mode 100644 index 0000000000..1067ae2c4a --- /dev/null +++ b/packages/emulators/tools/retroarch-joypads/gamepads/r33s_joypad.cfg @@ -0,0 +1,32 @@ +input_driver = "udev" +input_device = "r33s_joypad" +input_device_display_name = "R33S Joypad" + +input_b_btn = "0" +input_y_btn = "3" +input_select_btn = "8" +input_start_btn = "9" +input_a_btn = "1" +input_x_btn = "2" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" + +input_up_btn = "10" +input_down_btn = 11" +input_left_btn = "12" +input_right_btn = "13" + +# Hotkeys +input_enable_hotkey_btn = "8" +input_exit_emulator_btn = "9" + +input_menu_toggle_btn = "2" +input_fps_toggle_btn = "3" + +input_load_state_btn = "4" +input_save_state_btn = "5" + +input_rewind_btn = "6" +input_toggle_fast_forward_btn = "7" diff --git a/packages/graphics/SDL2/patches/RK3566/0003-Implement-librga-framebuffer-rotation.patch b/packages/graphics/SDL2/patches/RK3566/0003-Implement-librga-framebuffer-rotation.patch new file mode 100644 index 0000000000..c39da6d5cf --- /dev/null +++ b/packages/graphics/SDL2/patches/RK3566/0003-Implement-librga-framebuffer-rotation.patch @@ -0,0 +1,248 @@ +From d60c64d4142a0a706632c50b79474ee51464f973 Mon Sep 17 00:00:00 2001 +From: Johnny on Flame +Date: Sun, 6 Aug 2023 20:57:02 +0000 +Subject: [PATCH 3/7] Implement librga framebuffer rotation. + +--- + CMakeLists.txt | 2 +- + Makefile.in | 2 +- + src/video/kmsdrm/SDL_kmsdrmsym.h | 2 +- + src/video/kmsdrm/SDL_kmsdrmvideo.c | 75 +++++++++++++++++++++++---- + src/video/kmsdrm/SDL_kmsdrmvideo.h | 8 +++ + 6 files changed, 102 insertions(+), 13 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d6c82c819..374f24e85 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -663,7 +663,7 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC) + check_c_compiler_flag("" HAVE_NO_UNDEFINED) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(HAVE_NO_UNDEFINED AND NOT (USE_CLANG AND WINDOWS)) +- list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,--no-undefined") ++ list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,--no-undefined -lrga") + endif() + endif() + +diff --git a/Makefile.in b/Makefile.in +index eb4c4bc1a..5cd04eeec 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -23,7 +23,7 @@ CXX = @CXX@ + INCLUDE = @INCLUDE@ + CFLAGS = @BUILD_CFLAGS@ + EXTRA_CFLAGS = @EXTRA_CFLAGS@ +-LDFLAGS = @BUILD_LDFLAGS@ ++LDFLAGS = @BUILD_LDFLAGS@ -lrga + EXTRA_LDFLAGS = @EXTRA_LDFLAGS@ + LIBTOOL = @LIBTOOL@ + INSTALL = @INSTALL@ +diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h +index 8b9e7b257..b33373805 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmsym.h ++++ b/src/video/kmsdrm/SDL_kmsdrmsym.h +@@ -122,7 +122,7 @@ SDL_KMSDRM_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm, + SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf)) + SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf)) + SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo)) +- ++SDL_KMSDRM_SYM(int,gbm_bo_get_fd,(struct gbm_bo *bo)) + + #undef SDL_KMSDRM_MODULE + #undef SDL_KMSDRM_SYM +diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c +index ebe15fe9c..c5340afa8 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c ++++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c +@@ -44,6 +44,7 @@ + #include "SDL_kmsdrmopengles.h" + #include "SDL_kmsdrmmouse.h" + #include "SDL_kmsdrmdyn.h" ++#include + #include "SDL_kmsdrmvulkan.h" + #include + #include +@@ -51,6 +52,7 @@ + #include + #include + #include ++#include + + #ifdef __OpenBSD__ + static SDL_bool moderndri = SDL_FALSE; +@@ -68,6 +70,9 @@ static char kmsdrm_dri_cardpath[32]; + #define EGL_PLATFORM_GBM_MESA 0x31D7 + #endif + ++rga_info_t src_info = {0}; ++rga_info_t dst_info = {0}; ++ + static int get_driindex(void) + { + int available = -ENOENT; +@@ -330,6 +335,46 @@ static void KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data) + SDL_free(fb_info); + } + ++static void ++KMSDRM_InitRotateBuffer(_THIS, int frameWidth, int frameHeight) ++{ ++ int l_frameHeight; ++ SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); ++ ++ // initialize 2D raster graphic acceleration unit (RGA) ++ c_RkRgaInit(); ++ ++ l_frameHeight = frameHeight; ++ if(l_frameHeight % 32 != 0) { ++ l_frameHeight = (frameHeight + 32) & (~31); ++ } ++ ++ // create buffers for RGA with adjusted stride ++ for (int i = 0; i < RGA_BUFFERS_MAX; ++i) ++ { ++ viddata->rga_buffers[i] = KMSDRM_gbm_bo_create(viddata->gbm_dev, ++ frameWidth, l_frameHeight, ++ GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); ++ assert(viddata->rga_buffers[i]); ++ ++ viddata->rga_buffer_prime_fds[i] = KMSDRM_gbm_bo_get_fd(viddata->rga_buffers[i]); ++ } ++ viddata->rga_buffer_index = 0; ++ ++ // setup rotation ++ src_info.fd = -1; ++ src_info.mmuFlag = 1; ++ src_info.rotation = HAL_TRANSFORM_ROT_270; ++ ++ // swap width and height and adjust stride here because our source buffer is 480x854 ++ rga_set_rect(&src_info.rect, 0, 0, frameHeight, frameWidth, l_frameHeight, frameWidth, RK_FORMAT_BGRA_8888); ++ ++ dst_info.fd = -1; ++ dst_info.mmuFlag = 1; ++ ++ rga_set_rect(&dst_info.rect, 0, 0, frameWidth, frameHeight, frameWidth, frameHeight, RK_FORMAT_BGRA_8888); ++} ++ + KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) + { + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); +@@ -848,8 +893,8 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re + modedata->mode_index = mode_index; + + display.driverdata = dispdata; +- display.desktop_mode.w = dispdata->mode.hdisplay; +- display.desktop_mode.h = dispdata->mode.vdisplay; ++ display.desktop_mode.w = dispdata->mode.vdisplay; ++ display.desktop_mode.h = dispdata->mode.hdisplay; + display.desktop_mode.refresh_rate = dispdata->mode.vrefresh; + display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; + display.desktop_mode.driverdata = modedata; +@@ -1124,7 +1169,8 @@ static void KMSDRM_DirtySurfaces(SDL_Window *window) + or SetWindowFullscreen, send a fake event for now since the actual + recreation is deferred */ + KMSDRM_GetModeToSet(window, &mode); +- SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.hdisplay, mode.vdisplay); ++ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.vdisplay, mode.hdisplay); ++ + } + + /* This determines the size of the fb, which comes from the GBM surface +@@ -1159,13 +1205,13 @@ int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) + mode that's set in sync with what SDL_video.c thinks is set */ + KMSDRM_GetModeToSet(window, &dispdata->mode); + +- display->current_mode.w = dispdata->mode.hdisplay; +- display->current_mode.h = dispdata->mode.vdisplay; ++ display->current_mode.w = dispdata->mode.vdisplay; ++ display->current_mode.h = dispdata->mode.hdisplay; + display->current_mode.refresh_rate = dispdata->mode.vrefresh; + display->current_mode.format = SDL_PIXELFORMAT_ARGB8888; + + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, +- dispdata->mode.hdisplay, dispdata->mode.vdisplay, ++ dispdata->mode.vdisplay, dispdata->mode.hdisplay, + surface_fmt, surface_flags); + + if (!windata->gs) { +@@ -1189,7 +1235,7 @@ int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) + ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, +- dispdata->mode.hdisplay, dispdata->mode.vdisplay); ++ dispdata->mode.vdisplay, dispdata->mode.hdisplay); + + windata->egl_surface_dirty = SDL_FALSE; + +@@ -1272,8 +1318,8 @@ void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display) + modedata->mode_index = i; + } + +- mode.w = conn->modes[i].hdisplay; +- mode.h = conn->modes[i].vdisplay; ++ mode.w = conn->modes[i].vdisplay; ++ mode.h = conn->modes[i].hdisplay; + mode.refresh_rate = conn->modes[i].vrefresh; + mode.format = SDL_PIXELFORMAT_ARGB8888; + mode.driverdata = modedata; +@@ -1386,6 +1432,13 @@ void KMSDRM_DestroyWindow(_THIS, SDL_Window *window) + /*********************************************************************/ + SDL_free(window->driverdata); + window->driverdata = NULL; ++ for (int i = 0; i < RGA_BUFFERS_MAX; ++i) { ++ close(viddata->rga_buffer_prime_fds[i]); ++ } ++ if (src_info.fd) { ++ close(src_info.fd); ++ } ++ c_RkRgaDeInit(); + } + + /**********************************************************************/ +@@ -1404,6 +1457,7 @@ int KMSDRM_CreateWindow(_THIS, SDL_Window *window) + NativeDisplayType egl_display; + drmModeModeInfo *mode; + int ret = 0; ++ SDL_DisplayData *data; + + /* Allocate window internal data */ + windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); +@@ -1519,6 +1573,9 @@ int KMSDRM_CreateWindow(_THIS, SDL_Window *window) + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + ++ data = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; ++ KMSDRM_InitRotateBuffer(_this, data->mode.hdisplay, data->mode.vdisplay); ++ + /* Tell the app that the window has moved to top-left. */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, 0, 0); + +diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h +index b48f6ef70..890575fb8 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmvideo.h ++++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h +@@ -32,6 +32,10 @@ + #include + #include + #include ++#include ++#include ++ ++#define RGA_BUFFERS_MAX (3) + + typedef struct SDL_VideoData + { +@@ -53,6 +57,10 @@ typedef struct SDL_VideoData + open 1 FD and create 1 gbm device. */ + SDL_bool gbm_init; + ++ struct gbm_bo* rga_buffers[RGA_BUFFERS_MAX]; ++ int rga_buffer_prime_fds[RGA_BUFFERS_MAX]; ++ int rga_buffer_index; ++ + } SDL_VideoData; + + typedef struct SDL_DisplayModeData +-- +2.20.1 + diff --git a/packages/graphics/SDL2/patches/RK3566/0005-KMSDRM-Rotation-should-respect-panel-orientation.patch b/packages/graphics/SDL2/patches/RK3566/0005-KMSDRM-Rotation-should-respect-panel-orientation.patch new file mode 100644 index 0000000000..fdd4430394 --- /dev/null +++ b/packages/graphics/SDL2/patches/RK3566/0005-KMSDRM-Rotation-should-respect-panel-orientation.patch @@ -0,0 +1,356 @@ +From 0e53103957dd75be9140a474be343a6b7cc3cc9e Mon Sep 17 00:00:00 2001 +From: JohnnyonFlame +Date: Tue, 8 Aug 2023 03:55:43 -0300 +Subject: [PATCH 5/7] KMSDRM: Rotation should respect panel orientation. + +--- + src/video/kmsdrm/SDL_kmsdrmdyn.h | 8 ++ + src/video/kmsdrm/SDL_kmsdrmmouse.c | 60 +++++++++++++- + src/video/kmsdrm/SDL_kmsdrmvideo.c | 122 +++++++++++++++++++++++------ + src/video/kmsdrm/SDL_kmsdrmvideo.h | 2 + + 4 files changed, 166 insertions(+), 26 deletions(-) + +diff --git a/src/video/kmsdrm/SDL_kmsdrmdyn.h b/src/video/kmsdrm/SDL_kmsdrmdyn.h +index 319e3f0e3..e17e97e8e 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmdyn.h ++++ b/src/video/kmsdrm/SDL_kmsdrmdyn.h +@@ -32,6 +32,14 @@ + extern "C" { + #endif + ++enum drm_panel_orientation { ++ DRM_MODE_PANEL_ORIENTATION_UNKNOWN = -1, ++ DRM_MODE_PANEL_ORIENTATION_NORMAL = 0, ++ DRM_MODE_PANEL_ORIENTATION_LEFT_UP, ++ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, ++ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP, ++}; ++ + int SDL_KMSDRM_LoadSymbols(void); + void SDL_KMSDRM_UnloadSymbols(void); + +diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c +index 4c445ecf1..5dcaaaab6 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmmouse.c ++++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c +@@ -170,10 +170,30 @@ static int KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor) + } + + /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO. */ ++ uintptr_t src_buf = (uintptr_t)curdata->buffer; ++ uintptr_t dst_buf = (uintptr_t)ready_buffer; + for (i = 0; i < curdata->h; i++) { + for (j = 0; j < curdata->w; j++) { +- src_row = ((uint32_t*)curdata->buffer)[i * curdata->w + j]; +- SDL_memcpy(ready_buffer + ((curdata->w - j + 1) * bo_stride) + i, &src_row, 4); ++ uintptr_t src_pixel = src_buf + (i * curdata->w + j) * 4; ++ uintptr_t dst_pixel; ++ ++ int x, y; ++ if (dispdata->orientation == 0) { ++ x = j; ++ y = i; ++ } else if (dispdata->orientation == 1) { ++ x = curdata->w - i - 1; ++ y = j; ++ } else if (dispdata->orientation == 2) { ++ x = curdata->h - j - 1; ++ y = curdata->w - i - 1; ++ } else if (dispdata->orientation == 3) { ++ x = i; ++ y = curdata->h - j - 1; ++ } ++ ++ dst_pixel = dst_buf + (y * bo_stride + x * sizeof(uint32_t)); ++ *(uint32_t*)dst_pixel = *(uint32_t*)src_pixel; + } + } + +@@ -382,7 +402,23 @@ static int KMSDRM_WarpMouseGlobal(int x, int y) + if (dispdata->cursor_bo) { + int ret = 0; + +- ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, y, dispdata->mode.vdisplay + curdata->w - x); ++ if (dispdata->orientation == 0) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ x, ++ y); ++ } else if (dispdata->orientation == 1) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ dispdata->mode.hdisplay - curdata->h - y, ++ x); ++ } else if (dispdata->orientation == 2) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ dispdata->mode.hdisplay - curdata->w - x, ++ dispdata->mode.vdisplay - curdata->h - y); ++ } else if (dispdata->orientation == 3) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ y, ++ dispdata->mode.vdisplay - curdata->w - x); ++ } + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); +@@ -443,7 +479,23 @@ static void KMSDRM_MoveCursor(SDL_Cursor *cursor) + return; + } + +- ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, mouse->y, dispdata->mode.vdisplay - curdata->w - mouse->x); ++ if (dispdata->orientation == 0) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ mouse->x, ++ mouse->y); ++ } else if (dispdata->orientation == 1) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ dispdata->mode.hdisplay - curdata->h - mouse->y, ++ mouse->x); ++ } else if (dispdata->orientation == 2) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ dispdata->mode.hdisplay - curdata->w - mouse->x, ++ dispdata->mode.vdisplay - curdata->h - mouse->y); ++ } else if (dispdata->orientation == 3) { ++ ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, ++ mouse->y, ++ dispdata->mode.vdisplay - curdata->w - mouse->x); ++ } + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); +diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c +index c5340afa8..663c4707c 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c ++++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c +@@ -336,24 +336,27 @@ static void KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data) + } + + static void +-KMSDRM_InitRotateBuffer(_THIS, int frameWidth, int frameHeight) ++KMSDRM_InitRotateBuffer(_THIS, int orientation, int frameWidth, int frameHeight) + { +- int l_frameHeight; ++ int l_frameHeight, l_frameWidth; + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + + // initialize 2D raster graphic acceleration unit (RGA) + c_RkRgaInit(); + +- l_frameHeight = frameHeight; +- if(l_frameHeight % 32 != 0) { +- l_frameHeight = (frameHeight + 32) & (~31); ++ if (orientation & 1) { ++ l_frameWidth = frameWidth; ++ l_frameHeight = (frameHeight + 31) & (~31); ++ } else { ++ l_frameWidth = (frameWidth + 31) & (~31); ++ l_frameHeight = frameHeight; + } + + // create buffers for RGA with adjusted stride + for (int i = 0; i < RGA_BUFFERS_MAX; ++i) + { + viddata->rga_buffers[i] = KMSDRM_gbm_bo_create(viddata->gbm_dev, +- frameWidth, l_frameHeight, ++ l_frameWidth, l_frameHeight, + GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + assert(viddata->rga_buffers[i]); + +@@ -364,10 +367,18 @@ KMSDRM_InitRotateBuffer(_THIS, int frameWidth, int frameHeight) + // setup rotation + src_info.fd = -1; + src_info.mmuFlag = 1; +- src_info.rotation = HAL_TRANSFORM_ROT_270; ++ switch (orientation) { ++ default: src_info.rotation = 0; break; ++ case 1: src_info.rotation = HAL_TRANSFORM_ROT_90; break; ++ case 2: src_info.rotation = HAL_TRANSFORM_ROT_180; break; ++ case 3: src_info.rotation = HAL_TRANSFORM_ROT_270; break; ++ } + + // swap width and height and adjust stride here because our source buffer is 480x854 +- rga_set_rect(&src_info.rect, 0, 0, frameHeight, frameWidth, l_frameHeight, frameWidth, RK_FORMAT_BGRA_8888); ++ if (orientation & 1) ++ rga_set_rect(&src_info.rect, 0, 0, frameHeight, frameWidth, l_frameHeight, l_frameWidth, RK_FORMAT_BGRA_8888); ++ else ++ rga_set_rect(&src_info.rect, 0, 0, frameWidth, frameHeight, l_frameWidth, l_frameHeight, RK_FORMAT_BGRA_8888); + + dst_info.fd = -1; + dst_info.mmuFlag = 1; +@@ -617,6 +628,52 @@ static SDL_bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vr + return SDL_TRUE; + } + ++static int KMSDRM_ConnectorGetOrientation(uint32_t drm_fd, ++ uint32_t output_id) ++{ ++ uint32_t i; ++ SDL_bool found = SDL_FALSE; ++ uint64_t orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; ++ ++ drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, ++ output_id, ++ DRM_MODE_OBJECT_CONNECTOR); ++ ++ // Allow forcing specific orientations for debugging. ++ const char *override = SDL_getenv("SDL_KMSDRM_ORIENTATION"); ++ if (override && override[0] != '\0') { ++ int val = SDL_atoi(override); ++ return SDL_clamp(val, 0, 3); ++ } ++ ++ if (!props) { ++ return 0; ++ } ++ ++ for (i = 0; !found && i < props->count_props; ++i) { ++ drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]); ++ ++ if (!drm_prop) { ++ continue; ++ } ++ ++ if (SDL_strcasecmp(drm_prop->name, "panel orientation") == 0) { ++ orientation = props->prop_values[i]; ++ found = SDL_TRUE; ++ } ++ ++ KMSDRM_drmModeFreeProperty(drm_prop); ++ } ++ ++ /* librga expresses rotations clockwise. (e.g., dts = 90? rga = 270!) */ ++ switch (orientation) { ++ default: return 0; ++ case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: return 2; ++ case DRM_MODE_PANEL_ORIENTATION_LEFT_UP: return 1; ++ case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: return 3; ++ } ++} ++ + static SDL_bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd, + uint32_t output_id, + char const *name) +@@ -869,6 +926,8 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re + dispdata->connector = connector; + dispdata->crtc = crtc; + ++ /* store current connector orientation */ ++ dispdata->orientation = KMSDRM_ConnectorGetOrientation(viddata->drm_fd, connector->connector_id); + /* save previous vrr state */ + dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id); + /* try to enable vrr */ +@@ -893,8 +952,13 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re + modedata->mode_index = mode_index; + + display.driverdata = dispdata; +- display.desktop_mode.w = dispdata->mode.vdisplay; +- display.desktop_mode.h = dispdata->mode.hdisplay; ++ if (dispdata->orientation & 1) { ++ display.desktop_mode.w = dispdata->mode.vdisplay; ++ display.desktop_mode.h = dispdata->mode.hdisplay; ++ } else { ++ display.desktop_mode.w = dispdata->mode.hdisplay; ++ display.desktop_mode.h = dispdata->mode.vdisplay; ++ } + display.desktop_mode.refresh_rate = dispdata->mode.vrefresh; + display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; + display.desktop_mode.driverdata = modedata; +@@ -1158,8 +1222,10 @@ static void KMSDRM_GetModeToSet(SDL_Window *window, drmModeModeInfo *out_mode) + + static void KMSDRM_DirtySurfaces(SDL_Window *window) + { +- SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; + drmModeModeInfo mode; ++ SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; ++ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); ++ SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + /* Can't recreate EGL surfaces right now, need to wait until SwapWindow + so the correct thread-local surface and context state are available */ +@@ -1169,8 +1235,10 @@ static void KMSDRM_DirtySurfaces(SDL_Window *window) + or SetWindowFullscreen, send a fake event for now since the actual + recreation is deferred */ + KMSDRM_GetModeToSet(window, &mode); +- SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.vdisplay, mode.hdisplay); +- ++ if (dispdata->orientation & 1) ++ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.vdisplay, mode.hdisplay); ++ else ++ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.hdisplay, mode.vdisplay); + } + + /* This determines the size of the fb, which comes from the GBM surface +@@ -1204,14 +1272,18 @@ int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) + SDL_video.c expects. Hulk-smash the display's current_mode to keep the + mode that's set in sync with what SDL_video.c thinks is set */ + KMSDRM_GetModeToSet(window, &dispdata->mode); +- +- display->current_mode.w = dispdata->mode.vdisplay; +- display->current_mode.h = dispdata->mode.hdisplay; ++ if (dispdata->orientation & 1) { ++ display->current_mode.w = dispdata->mode.vdisplay; ++ display->current_mode.h = dispdata->mode.hdisplay; ++ } else { ++ display->current_mode.w = dispdata->mode.hdisplay; ++ display->current_mode.h = dispdata->mode.vdisplay; ++ } + display->current_mode.refresh_rate = dispdata->mode.vrefresh; + display->current_mode.format = SDL_PIXELFORMAT_ARGB8888; + + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, +- dispdata->mode.vdisplay, dispdata->mode.hdisplay, ++ display->current_mode.w, display->current_mode.h, + surface_fmt, surface_flags); + + if (!windata->gs) { +@@ -1235,7 +1307,7 @@ int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) + ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, +- dispdata->mode.vdisplay, dispdata->mode.hdisplay); ++ display->current_mode.w, display->current_mode.h); + + windata->egl_surface_dirty = SDL_FALSE; + +@@ -1318,8 +1390,14 @@ void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display) + modedata->mode_index = i; + } + +- mode.w = conn->modes[i].vdisplay; +- mode.h = conn->modes[i].hdisplay; ++ if (dispdata->orientation & 1) { ++ mode.w = conn->modes[i].vdisplay; ++ mode.h = conn->modes[i].hdisplay; ++ } else { ++ mode.w = conn->modes[i].hdisplay; ++ mode.h = conn->modes[i].vdisplay; ++ } ++ + mode.refresh_rate = conn->modes[i].vrefresh; + mode.format = SDL_PIXELFORMAT_ARGB8888; + mode.driverdata = modedata; +@@ -1573,8 +1651,8 @@ int KMSDRM_CreateWindow(_THIS, SDL_Window *window) + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + +- data = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; +- KMSDRM_InitRotateBuffer(_this, data->mode.hdisplay, data->mode.vdisplay); ++ data = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; ++ KMSDRM_InitRotateBuffer(_this, dispdata->orientation, data->mode.hdisplay, data->mode.vdisplay); + + /* Tell the app that the window has moved to top-left. */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, 0, 0); +diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h +index 890575fb8..8d2dc646f 100644 +--- a/src/video/kmsdrm/SDL_kmsdrmvideo.h ++++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h +@@ -78,6 +78,8 @@ typedef struct SDL_DisplayData + + drmModeCrtc *saved_crtc; /* CRTC to restore on quit */ + SDL_bool saved_vrr; ++ ++ uint64_t orientation; + + /* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct, + because setting/unsetting up these is done on window creation/destruction, +-- +2.20.1 + diff --git a/packages/graphics/SDL2/patches/RK3566/0006-limit-rga-buffering-when-egl.patch b/packages/graphics/SDL2/patches/RK3566/0006-limit-rga-buffering-when-egl.patch new file mode 100644 index 0000000000..dbd2938124 --- /dev/null +++ b/packages/graphics/SDL2/patches/RK3566/0006-limit-rga-buffering-when-egl.patch @@ -0,0 +1,59 @@ +diff -rupN SDL2-2.28.5.orig/src/video/kmsdrm/SDL_kmsdrmopengles.c SDL2-2.28.5/src/video/kmsdrm/SDL_kmsdrmopengles.c +--- SDL2-2.28.5.orig/src/video/kmsdrm/SDL_kmsdrmopengles.c 2024-01-30 16:22:00.475039122 +0000 ++++ SDL2-2.28.5/src/video/kmsdrm/SDL_kmsdrmopengles.c 2024-01-30 17:56:52.799111194 +0000 +@@ -29,11 +29,15 @@ + #include "SDL_kmsdrmopengles.h" + #include "SDL_kmsdrmdyn.h" + #include ++#include + + #ifndef EGL_PLATFORM_GBM_MESA + #define EGL_PLATFORM_GBM_MESA 0x31D7 + #endif + ++extern rga_info_t src_info; ++extern rga_info_t dst_info; ++ + /* EGL implementation of SDL OpenGL support */ + + void KMSDRM_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor) +@@ -92,6 +96,7 @@ int KMSDRM_GLES_SwapWindow(_THIS, SDL_Wi + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + KMSDRM_FBInfo *fb_info; + int ret = 0; ++ struct gbm_bo* rga_buffer = NULL; + + /* Always wait for the previous issued flip before issuing a new one, + even if you do async flips. */ +@@ -135,7 +140,30 @@ int KMSDRM_GLES_SwapWindow(_THIS, SDL_Wi + } + + /* Get an actual usable fb for the next front buffer. */ +- fb_info = KMSDRM_FBFromBO(_this, windata->next_bo); ++ if (dispdata->orientation == 0) { ++ fb_info = KMSDRM_FBFromBO(_this, windata->next_bo); ++ } else { ++ if (src_info.fd) { ++ close(src_info.fd); ++ } ++ src_info.fd = KMSDRM_gbm_bo_get_fd(windata->next_bo); ++ dst_info.fd = viddata->rga_buffer_prime_fds[viddata->rga_buffer_index]; ++ if (c_RkRgaBlit(&src_info, &dst_info, NULL) < 0) { ++ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, ++ "Failed to rga blit\n"); ++ } ++ ++ rga_buffer = viddata->rga_buffers[viddata->rga_buffer_index]; ++ fb_info = KMSDRM_FBFromBO(_this, rga_buffer); ++ ++ if (!fb_info) { ++ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not get a framebuffer"); ++ return 0; ++ } ++ ++ viddata->rga_buffer_index = (viddata->rga_buffer_index + 1) % RGA_BUFFERS_MAX; ++ } ++ + if (fb_info == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not get a framebuffer"); + return 0; diff --git a/packages/graphics/mesa/package.mk b/packages/graphics/mesa/package.mk index 178f7d5cc5..e8f518868c 100644 --- a/packages/graphics/mesa/package.mk +++ b/packages/graphics/mesa/package.mk @@ -10,19 +10,20 @@ PKG_TOOLCHAIN="meson" PKG_PATCH_DIRS+=" ${DEVICE}" case ${DEVICE} in - RK35*) + RK3588*) PKG_VERSION="120202c675749c5ef81ae4c8cdc30019b4de08f4" PKG_SITE="https://gitlab.com/panfork/mesa" PKG_URL="${PKG_SITE}.git" PKG_GIT_CLONE_BRANCH="csf" ;; - RK3399) #Stable Mesa appears to be broken on the RK3399 build currently, using upstream dev - PKG_VERSION="3ee633920618de559f6cf76225b1c2b27256facc" + RK33*) #Using upstream dev for panfrost + PKG_VERSION="97efa57531b826edf62b00fd4dc26d7568ff941b" PKG_SITE="https://gitlab.freedesktop.org/mesa/mesa" PKG_URL="${PKG_SITE}.git" + PKG_PATCH_DIRS+=" panfrost" ;; *) - PKG_VERSION="23.3.3" + PKG_VERSION="23.3.4" PKG_SITE="http://www.mesa3d.org/" PKG_URL="https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-${PKG_VERSION}/mesa-mesa-${PKG_VERSION}.tar.gz" ;; diff --git a/packages/graphics/mesa/patches/panfrost/26811-egl_v1.5.patch b/packages/graphics/mesa/patches/panfrost/26811-egl_v1.5.patch new file mode 100644 index 0000000000..0bc8da5446 --- /dev/null +++ b/packages/graphics/mesa/patches/panfrost/26811-egl_v1.5.patch @@ -0,0 +1,58 @@ +From 12254d89fcf3adb27ed5d1191449d06207eb61f1 Mon Sep 17 00:00:00 2001 +From: Urja Rannikko +Date: Sun, 24 Dec 2023 15:54:52 +0200 +Subject: [PATCH] panfrost: Stub implementation of + PIPE_CAP_DEVICE_RESET_STATUS_QUERY + +This enables EGL_EXT_create_context_robustness, which is the only +extension missing from panfrost (on my T760, atleast) to report +EGL version 1.5. Recent kicad (built with wxWidgets EGL canvas) +requires EGL 1.5 to enable acceleration. + +Signed-off-by: Urja Rannikko +--- + src/gallium/drivers/panfrost/pan_context.c | 7 +++++++ + src/gallium/drivers/panfrost/pan_screen.c | 3 +++ + 2 files changed, 10 insertions(+) + +diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c +index e1fed545c4bcf..bfd9de4d23231 100644 +--- a/src/gallium/drivers/panfrost/pan_context.c ++++ b/src/gallium/drivers/panfrost/pan_context.c +@@ -867,6 +867,12 @@ panfrost_fence_server_sync(struct pipe_context *pctx, + close(fd); + } + ++static enum pipe_reset_status ++panfrost_get_device_reset_status(struct pipe_context *pipe) ++{ ++ return PIPE_NO_RESET; ++} ++ + struct pipe_context * + panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags) + { +@@ -883,6 +889,7 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags) + + gallium->create_fence_fd = panfrost_create_fence_fd; + gallium->fence_server_sync = panfrost_fence_server_sync; ++ gallium->get_device_reset_status = panfrost_get_device_reset_status; + + gallium->flush = panfrost_flush; + gallium->clear = panfrost_clear; +diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c +index 876833e799192..2036a63bd2955 100644 +--- a/src/gallium/drivers/panfrost/pan_screen.c ++++ b/src/gallium/drivers/panfrost/pan_screen.c +@@ -369,6 +369,9 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) + case PIPE_CAP_NATIVE_FENCE_FD: + return 1; + ++ case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: ++ return 1; ++ + default: + return u_pipe_screen_get_param_defaults(screen, param); + } +-- +GitLab diff --git a/packages/hardware/quirks/autostart/095-turbo-mode b/packages/hardware/quirks/autostart/095-turbo-mode new file mode 100644 index 0000000000..2d063b7ddd --- /dev/null +++ b/packages/hardware/quirks/autostart/095-turbo-mode @@ -0,0 +1,16 @@ +#!/bin/sh + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +# Get Turbo Mode state. +TURBO_MODE_STATE=$(get_setting "enable.turbo-mode") +if [ ! -n "${TURBO_MODE_STATE}" ]; then + TURBO_MODE_STATE=0 + set_setting "enable.turbo-mode" "0" +fi + +# Set turbo-mode at boot +echo ${TURBO_MODE_STATE} > /sys/devices/system/cpu/cpufreq/boost diff --git a/packages/hardware/quirks/devices/AYANEO AIR Plus/010-dpms b/packages/hardware/quirks/devices/AYANEO AIR Plus/010-dpms new file mode 100644 index 0000000000..f4a112017b --- /dev/null +++ b/packages/hardware/quirks/devices/AYANEO AIR Plus/010-dpms @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat <>/storage/.config/profile.d/001-device_config +DEVICE_SLEEP_DPMS="false" +EOF diff --git a/packages/hardware/quirks/devices/AYANEO AIR Plus/bin/ledcontrol b/packages/hardware/quirks/devices/AYANEO AIR Plus/bin/ledcontrol index 3c301539b7..4a68c19e5a 100755 --- a/packages/hardware/quirks/devices/AYANEO AIR Plus/bin/ledcontrol +++ b/packages/hardware/quirks/devices/AYANEO AIR Plus/bin/ledcontrol @@ -303,6 +303,9 @@ case ${LEDBRIGHTNESS} in esac case ${1} in + poweroff) + led_state 0x31 + ;; off) led_state 0x31 set_setting led.color off diff --git a/packages/hardware/quirks/devices/AYANEO AIR/010-dpms b/packages/hardware/quirks/devices/AYANEO AIR/010-dpms new file mode 100644 index 0000000000..f4a112017b --- /dev/null +++ b/packages/hardware/quirks/devices/AYANEO AIR/010-dpms @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat <>/storage/.config/profile.d/001-device_config +DEVICE_SLEEP_DPMS="false" +EOF diff --git a/packages/hardware/quirks/devices/AYANEO AIR/bin/ledcontrol b/packages/hardware/quirks/devices/AYANEO AIR/bin/ledcontrol index ba9bd87474..83da486db4 100755 --- a/packages/hardware/quirks/devices/AYANEO AIR/bin/ledcontrol +++ b/packages/hardware/quirks/devices/AYANEO AIR/bin/ledcontrol @@ -157,6 +157,9 @@ case $1 in color 1 ${LEDBRIGHTNESS} set_setting led.color purple ;; + poweroff) + off + ;; off) off set_setting led.color off diff --git a/packages/hardware/quirks/devices/AYANEO AYANEO 2S/bin/ledcontrol b/packages/hardware/quirks/devices/AYANEO AYANEO 2S/bin/ledcontrol index ba9bd87474..83da486db4 100755 --- a/packages/hardware/quirks/devices/AYANEO AYANEO 2S/bin/ledcontrol +++ b/packages/hardware/quirks/devices/AYANEO AYANEO 2S/bin/ledcontrol @@ -157,6 +157,9 @@ case $1 in color 1 ${LEDBRIGHTNESS} set_setting led.color purple ;; + poweroff) + off + ;; off) off set_setting led.color off diff --git a/packages/hardware/quirks/devices/Game Console R33S/001-device_config b/packages/hardware/quirks/devices/Game Console R33S/001-device_config new file mode 100644 index 0000000000..e326155a6a --- /dev/null +++ b/packages/hardware/quirks/devices/Game Console R33S/001-device_config @@ -0,0 +1,14 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_VOLUMECTL="true" +DEVICE_POWER_LED="false" +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_BRIGHTNESS="128" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/packages/hardware/quirks/devices/Game Console R33S/002-disable-led b/packages/hardware/quirks/devices/Game Console R33S/002-disable-led new file mode 100644 index 0000000000..d917e34827 --- /dev/null +++ b/packages/hardware/quirks/devices/Game Console R33S/002-disable-led @@ -0,0 +1,15 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +# Set export GPIO for Power LED +if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export +fi + +#Disable blue led on R33S +echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction +echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value diff --git a/packages/hardware/quirks/devices/Game Console R33S/050-game-configs b/packages/hardware/quirks/devices/Game Console R33S/050-game-configs new file mode 100644 index 0000000000..b303090562 --- /dev/null +++ b/packages/hardware/quirks/devices/Game Console R33S/050-game-configs @@ -0,0 +1,262 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +#Set mupen64-plus-sa config for R33S +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.r33s" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.r33s /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for OGA +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.r33s" ]; then + mv /storage/.config/drastic/config/drastic.cfg.r33s /storage/.config/drastic/config/drastic.cfg +fi + + +#Set gzoom config for R33S +if [ ! -d "/storage/.config/gzdoom" ]; then + cp -r "/usr/config/gzdoom" "/storage/.config/" +fi + +#Set gzdoom settings +if grep R33S -q "/storage/.config/gzdoom/gzdoom.ini" +then + exit 1 +else +sed -i '/^[Doom.Bindings]/c\[Doom.Bindings] #R33S' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^vid_defheight=/c\vid_defheight=480' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^vid_defwidth=/c\vid_defwidth=640' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy1=/c\Joy1=+use' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy5=/c\Joy5=+speed' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy6=/c\Joy6=+attack' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy7=/c\Joy7=+moveleft' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy8=/c\Joy8=+moveright' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy9=/c\Joy9=menu_main' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy11=/c\Joy11=+forward' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy12=/c\Joy12=+back' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy13=/c\Joy13=+left' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy14=/c\Joy14=+right' /storage/.config/gzdoom/gzdoom.ini +sed -i '/^Joy2=/c\Joy2=+attack' /storage/.config/gzdoom/gzdoom.ini +fi + +#Set ppsspp config for R33S +if [ ! -d "/storage/.config/ppsspp" ]; then + mkdir -p "/storage/.config/ppsspp" + cp -r "/usr/config/ppsspp" "/storage/.config/" +fi + +#Map ppsspp controls +if grep R33S -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#R33S +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +Fast-forward = 1-61 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +EOF +fi + +#Set flycast ra config for R33S +if [ ! -d "/storage/remappings/Flycast" ]; then + mkdir -p "/storage/remappings/Flycast" +fi + +#Map flycast ra controls for R33S +if grep R33S -q "/storage/remappings/Flycast/Flycast.rmp" +then + exit 1 +else +cat </storage/remappings/Flycast/Flycast.rmp +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_down = "18" +input_player1_btn_left = "17" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +EOF +fi + +#Set Mupen64Plus GLES2 ra config for R33S +if [ ! -d "/storage/remappings/Mupen64Plus GLES2" ]; then + mkdir -p "/storage/remappings/Mupen64Plus GLES2" +fi + +#Map Mupen64Plus GLES2 ra controls for R33S +if grep R33S -q "/storage/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp" +then + exit 1 +else +cat <"/storage/remappings/Mupen64Plus GLES2/Mupen64Plus GLES2.rmp" +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +EOF +fi + +#Set Mupen64Plus-Next ra config for R33S +if [ ! -d "/storage/remappings/Mupen64Plus-Next" ]; then + mkdir -p "/storage/remappings/Mupen64Plus-Next" +fi + +#Map Mupen64Plus-Next ra controls for R33S +if grep R33S -q "/storage/remappings/Mupen64Plus-Next/Mupen64Plus-Next.rmp" +then + exit 1 +else +cat </storage/remappings/Mupen64Plus-Next/Mupen64Plus-Next.rmp +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4" +EOF +fi + +#Set ParaLLEl N64 ra config for R33S +if [ ! -d "/storage/remappings/ParaLLEl N64" ]; then + mkdir -p "/storage/remappings/ParaLLEl N64" +fi + +#Map ParaLLEl N64 ra controls for R33S +if grep R33S -q "/storage/remappings/ParaLLEl N64/ParaLLEl N64.rmp" +then + exit 1 +else +cat <"/storage/remappings/ParaLLEl N64/ParaLLEl N64.rmp" +#R33S +input_libretro_device_p1 = "1" +input_libretro_device_p2 = "1" +input_libretro_device_p3 = "1" +input_libretro_device_p4 = "1" +input_libretro_device_p5 = "1" +input_player1_analog_dpad_mode = "0" +input_player1_btn_a = "22" +input_player1_btn_down = "18" +input_player1_btn_l = "12" +input_player1_btn_l2 = "21" +input_player1_btn_left = "17" +input_player1_btn_r2 = "20" +input_player1_btn_right = "16" +input_player1_btn_up = "19" +input_player1_btn_x = "23" +input_player1_stk_l_x+ = "-1" +input_player1_stk_l_x- = "-1" +input_player1_stk_l_y+ = "-1" +input_player1_stk_l_y- = "-1" +input_player1_stk_r_x+ = "-1" +input_player1_stk_r_x- = "-1" +input_player1_stk_r_y+ = "-1" +input_player1_stk_r_y- = "-1" +input_player2_analog_dpad_mode = "0" +input_player3_analog_dpad_mode = "0" +input_player4_analog_dpad_mode = "0" +input_player5_analog_dpad_mode = "0" +input_remap_port_p1 = "0" +input_remap_port_p2 = "1" +input_remap_port_p3 = "2" +input_remap_port_p4 = "3" +input_remap_port_p5 = "4 +EOF +fi diff --git a/packages/hardware/quirks/devices/MagicX XU10/001-device_config b/packages/hardware/quirks/devices/MagicX XU10/001-device_config index 3113868817..52c093a077 100644 --- a/packages/hardware/quirks/devices/MagicX XU10/001-device_config +++ b/packages/hardware/quirks/devices/MagicX XU10/001-device_config @@ -10,6 +10,5 @@ DEVICE_PLAYBACK_PATH_SPK="SPK" DEVICE_PLAYBACK_PATH_HP="HP" DEVICE_BRIGHTNESS="128" DEVICE_BATTERY_LED_STATUS="true" -DEVICE_PWR_LED_GPIO="77" DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" EOF diff --git a/packages/hardware/quirks/devices/MagicX XU10/004-game-configs b/packages/hardware/quirks/devices/MagicX XU10/004-game-configs index 9715a86283..94be73b27b 100644 --- a/packages/hardware/quirks/devices/MagicX XU10/004-game-configs +++ b/packages/hardware/quirks/devices/MagicX XU10/004-game-configs @@ -48,8 +48,8 @@ Square = 10-191 Triangle = 10-188 Start = 10-197 Select = 10-196 -L = 10-194 -R = 10-195 +L = 10-193 +R = 10-192 An.Up = 10-4003 An.Down = 10-4002 An.Left = 10-4001 diff --git a/packages/hardware/quirks/devices/MagicX XU10/bin/battery_led_status b/packages/hardware/quirks/devices/MagicX XU10/bin/battery_led_status new file mode 100644 index 0000000000..8c782f32d8 --- /dev/null +++ b/packages/hardware/quirks/devices/MagicX XU10/bin/battery_led_status @@ -0,0 +1,67 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2020-present Fewtarius + +# Simple script to watch the battery capacity and +# turn the power LED to different states: +# 0-10% flashing blue and teal +# 11-20% teal +# 21+% blue +# charging purple +# fully charged white + +. /etc/profile + +function set_led() { + case $1 in + white) + echo 1 > /sys/class/leds/red\:charging/brightness + echo 1 > /sys/class/leds/green\:status/brightness + ;; + purple) + echo 1 > /sys/class/leds/red\:charging/brightness + echo 0 > /sys/class/leds/green\:status/brightness + ;; + blue) + echo 0 > /sys/class/leds/red\:charging/brightness + echo 0 > /sys/class/leds/green\:status/brightness + ;; + teal) + echo 0 > /sys/class/leds/red\:charging/brightness + echo 1 > /sys/class/leds/green\:status/brightness + ;; + esac +} + + +while true +do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + if [[ ${STAT} == "Discharging" ]] + then + if (( ${CAP} <= 10 )) + then + for ctr in $(seq 1 1 5) + do + set_led teal + sleep .5 + set_led blue + sleep .5 + done + continue + elif (( ${CAP} <= 20 )) + then + set_led teal + else + set_led blue + fi + elif (( ${CAP} <= 95 )) + then + set_led purple + else + set_led white + fi + sleep 15 +done diff --git a/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs b/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs index b1af9bcb2e..f529d03c99 100644 --- a/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs +++ b/packages/hardware/quirks/devices/ODROID-GO Advance Black Edition/050-game_configs @@ -16,11 +16,10 @@ fi #Set drastic-sa config for OGA if [ ! -d "/storage/.config/drastic" ]; then mkdir -p "/storage/.config/drastic" - cp -r "/usr/config/drastic" "/storage/.config/" + cp -r "/usr/config/drastic" "/storage/.config/" fi if [ -f "/storage/.config/drastic/config/drastic.cfg.ogabe" ]; then - rm /storage/.config/drastic/config/drastic.cfg - mv /storage/.config/drastic/config/drastic.cfg.oga /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.ogabe /storage/.config/drastic/config/drastic.cfg fi #Set gzdoom resolution diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3/050-audio_path b/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-audio_path similarity index 100% rename from packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3/050-audio_path rename to packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-audio_path diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3/050-game_configs b/packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-game_configs similarity index 100% rename from packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3/050-game_configs rename to packages/hardware/quirks/devices/Powkiddy RGB10 MAX 3 Pro/050-game_configs diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/010-governors b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/010-governors new file mode 100755 index 0000000000..e1a4622419 --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/010-governors @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-governors +CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0") +GPU_FREQ="/sys/devices/platform/fde60000.gpu/devfreq/fde60000.gpu" +DMC_FREQ="/sys/devices/platform/dmc/devfreq/dmc" +EOF diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/020-gpios b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/020-gpios new file mode 100755 index 0000000000..357fcb1087 --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/020-gpios @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-gpios +DEVICE_WIFI="0" +DEVICE_PWM_MOTOR="pwmchip1" +EOF + +. /storage/.config/profile.d/020-gpios +# Enable PWM for rumble and turn rumble off during startup. +echo 0 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/export +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/period +echo 1 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/enable +echo 1000000 > /sys/class/pwm/${DEVICE_PWM_MOTOR}/pwm0/duty_cycle diff --git a/packages/sysutils/system-utils/sources/autostart/AMD64/003-controllerled b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/030-suspend_mode similarity index 50% rename from packages/sysutils/system-utils/sources/autostart/AMD64/003-controllerled rename to packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/030-suspend_mode index 1773bcbb9f..523d9736bb 100755 --- a/packages/sysutils/system-utils/sources/autostart/AMD64/003-controllerled +++ b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/030-suspend_mode @@ -2,8 +2,13 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) -# Minimal OS variable loading for performance . /etc/profile.d/001-functions -tocon "Configuring LEDs..." -/usr/bin/ledcontrol +MYSLEEPMODE=$(get_setting system.suspendmode) +if [ -z "${MYSLEEPMODE}" ] +then + /usr/bin/suspendmode mem +fi + +echo s2idle >/sys/power/mem_sleep + diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/040-display b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/040-display new file mode 100755 index 0000000000..107ddab321 --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/040-display @@ -0,0 +1,16 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +# Configure default contrast saturation and hue values +for PROPERTY in brightness contrast saturation hue +do + MYVAL=$(get_setting display.${PROPERTY}) + if [ -z "${MYVAL}" ] + then + MYVAL=$(drm_tool list | sed -n '/Connector: 133/,$p' | awk '/'${PROPERTY}'/ {print $5}') + fi + paneladj ${PROPERTY} ${MYVAL} +done diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-audio_path b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-audio_path new file mode 100755 index 0000000000..f5860cdb57 --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-audio_path @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_PLAYBACK_PATH="Playback Path" +EOF diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-game_configs b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-game_configs new file mode 100755 index 0000000000..50b56be0c0 --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB10 Max 3/050-game_configs @@ -0,0 +1,14 @@ + +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + cp -rf /usr/config/gzdoom /storage/.config/ + sed -i '/Joy10=/c\Joy10=togglemap; + /Joy9=/c\Joy9=menu_main; + /vid_defheight=/c\vid_defheight=480; + /vid_defwidth=/c\vid_defwidth=640' /storage/.config/gzdoom/gzdoom.ini +fi diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config b/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config index 1069761684..5ce9862c95 120000 --- a/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config +++ b/packages/hardware/quirks/devices/Powkiddy RGB10/001-device_config @@ -1 +1 @@ -../ODROID-GO Advance/001-device_config \ No newline at end of file +../ODROID-GO Advance Black Edition/001-device_config \ No newline at end of file diff --git a/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs b/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs index addb9132e4..0a41c8be26 120000 --- a/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs +++ b/packages/hardware/quirks/devices/Powkiddy RGB10/050-game_configs @@ -1 +1 @@ -../ODROID-GO Advance/050-game_configs \ No newline at end of file +../ODROID-GO Advance Black Edition/050-game_configs \ No newline at end of file diff --git a/packages/hardware/quirks/devices/Powkiddy RGB20S/001-device_config b/packages/hardware/quirks/devices/Powkiddy RGB20S/001-device_config new file mode 100644 index 0000000000..e326155a6a --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB20S/001-device_config @@ -0,0 +1,14 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +# Device Features +DEVICE_VOLUMECTL="true" +DEVICE_POWER_LED="false" +DEVICE_PLAYBACK_PATH_SPK="HP" +DEVICE_PLAYBACK_PATH_HP="SPK" +DEVICE_BRIGHTNESS="128" +DEVICE_PWR_LED_GPIO="77" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" +EOF diff --git a/packages/hardware/quirks/devices/Powkiddy RGB20S/002-disable-led b/packages/hardware/quirks/devices/Powkiddy RGB20S/002-disable-led new file mode 100644 index 0000000000..d917e34827 --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB20S/002-disable-led @@ -0,0 +1,15 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +# Set export GPIO for Power LED +if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export +fi + +#Disable blue led on R33S +echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction +echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value diff --git a/packages/hardware/quirks/devices/Powkiddy RGB20S/050-game-configs b/packages/hardware/quirks/devices/Powkiddy RGB20S/050-game-configs new file mode 100644 index 0000000000..a27895eebd --- /dev/null +++ b/packages/hardware/quirks/devices/Powkiddy RGB20S/050-game-configs @@ -0,0 +1,65 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +#Set mupen64-plus-sa config for RGB20S, can use same profile as OGS +if [ ! -d "/storage/.config/mupen64plus" ]; then + mkdir -p "/storage/.config/mupen64plus/" + cp -r /usr/local/share/mupen64plus/mupen64plus.cfg* /storage/.config/mupen64plus/ +fi +if [ -f "/storage/.config/mupen64plus/mupen64plus.cfg.ogs" ]; then + rm /storage/.config/mupen64plus/mupen64plus.cfg + mv /storage/.config/mupen64plus/mupen64plus.cfg.ogs /storage/.config/mupen64plus/mupen64plus.cfg +fi + +#Set drastic-sa config for RGB20S +if [ ! -d "/storage/.config/drastic" ]; then + mkdir -p "/storage/.config/drastic" + cp -r "/usr/config/drastic" "/storage/.config/" +fi +if [ -f "/storage/.config/drastic/config/drastic.cfg.rgb20s" ]; then + rm /storage/.config/drastic/config/drastic.cfg + mv /storage/.config/drastic/config/drastic.cfg.rgb20s /storage/.config/drastic/config/drastic.cfg +fi + +#Set up gzdoom +if [ ! -d "/storage/.config/gzdoom/" ]; then + sed -i '/vid_defheight=/c\vid_defheight=640' /storage/.config/gzdoom/gzdoom.ini + sed -i '/vid_defwidth=/c\vid_defwidth=478' /storage/.config/gzdoom/gzdoom.ini +fi + +#Map ppsspp controls +if grep RGB20S -q "/storage/.config/ppsspp/PSP/SYSTEM/controls.ini" +then + exit 1 +else +cat </storage/.config/ppsspp/PSP/SYSTEM/controls.ini +#RGB20S +[ControlMapping] +Up = 10-19 +Down = 10-20 +Left = 10-21 +Right = 10-22 +Circle = 10-189 +Cross = 10-190 +Square = 10-188 +Triangle = 10-191 +Start = 10-197 +Select = 10-196 +L = 10-193 +R = 10-192 +An.Up = 10-4003 +An.Down = 10-4002 +An.Left = 10-4001 +An.Right = 10-4000 +Pause = 10-106 +Save State = 10-4010 +Load State = 10-4008 +RightAn.Up = 10-4007 +RightAn.Down = 10-4006 +RightAn.Left = 10-4005 +RightAn.Right = 10-4004 +EOF +fi diff --git a/packages/hardware/quirks/devices/ayn Loki Max/010-dpms b/packages/hardware/quirks/devices/ayn Loki Max/010-dpms new file mode 100755 index 0000000000..ca371e8a2d --- /dev/null +++ b/packages/hardware/quirks/devices/ayn Loki Max/010-dpms @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-dpms +DEVICE_SLEEP_DPMS="false" +EOF diff --git a/packages/hardware/quirks/devices/ayn Loki Max/bin/ledcontrol b/packages/hardware/quirks/devices/ayn Loki Max/bin/ledcontrol index c023d5fa8d..866931afcc 100755 --- a/packages/hardware/quirks/devices/ayn Loki Max/bin/ledcontrol +++ b/packages/hardware/quirks/devices/ayn Loki Max/bin/ledcontrol @@ -151,6 +151,9 @@ case $1 in ec_save set_setting led.color white ;; + poweroff) + off + ;; off) off set_setting led.color off diff --git a/packages/hardware/quirks/devices/ayn Loki Zero/001-device_config b/packages/hardware/quirks/devices/ayn Loki Zero/001-device_config old mode 100644 new mode 100755 index 1ab12d92fd..123af288c5 --- a/packages/hardware/quirks/devices/ayn Loki Zero/001-device_config +++ b/packages/hardware/quirks/devices/ayn Loki Zero/001-device_config @@ -7,9 +7,6 @@ ### Set the default device configuration cat </storage/.config/profile.d/001-device_config DEVICE_BASE_TDP="6w" -DEVICE_LED_CONTROL="false" -DEVICE_LED_BRIGHTNESS="false" -DEVICE_HAS_FAN="false" DEVICE_VOLUMECTL="true" DEVICE_BRIGHTNESS="hardware" EOF diff --git a/packages/hardware/quirks/devices/ayn Loki Zero/010-dpms b/packages/hardware/quirks/devices/ayn Loki Zero/010-dpms new file mode 100755 index 0000000000..ca371e8a2d --- /dev/null +++ b/packages/hardware/quirks/devices/ayn Loki Zero/010-dpms @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-dpms +DEVICE_SLEEP_DPMS="false" +EOF diff --git a/packages/hardware/quirks/devices/ayn Loki Zero/020-audio_latency b/packages/hardware/quirks/devices/ayn Loki Zero/020-audio_latency old mode 100644 new mode 100755 diff --git a/packages/hardware/quirks/devices/ayn Loki Zero/bin/ledcontrol b/packages/hardware/quirks/devices/ayn Loki Zero/bin/ledcontrol index c023d5fa8d..866931afcc 100755 --- a/packages/hardware/quirks/devices/ayn Loki Zero/bin/ledcontrol +++ b/packages/hardware/quirks/devices/ayn Loki Zero/bin/ledcontrol @@ -151,6 +151,9 @@ case $1 in ec_save set_setting led.color white ;; + poweroff) + off + ;; off) off set_setting led.color off diff --git a/packages/hardware/quirks/package.mk b/packages/hardware/quirks/package.mk index cff5bbd52a..91053eba91 100644 --- a/packages/hardware/quirks/package.mk +++ b/packages/hardware/quirks/package.mk @@ -22,3 +22,7 @@ makeinstall_target() { fi chmod -R 0755 ${INSTALL}/usr/lib/autostart/quirks } + +post_install() { + enable_service led-poweroff.service +} diff --git a/packages/hardware/quirks/platforms/AMD64/001-device_config b/packages/hardware/quirks/platforms/AMD64/001-device_config index 309b6dd555..29d2bef44d 100755 --- a/packages/hardware/quirks/platforms/AMD64/001-device_config +++ b/packages/hardware/quirks/platforms/AMD64/001-device_config @@ -7,9 +7,6 @@ ### Set the default device configuration cat </storage/.config/profile.d/001-device_config DEVICE_BASE_TDP="15w" -DEVICE_LED_CONTROL="false" -DEVICE_LED_BRIGHTNESS="false" -DEVICE_HAS_FAN="false" DEVICE_VOLUMECTL="true" DEVICE_BRIGHTNESS="hardware" EOF diff --git a/packages/hardware/quirks/platforms/AMD64/010-dpms b/packages/hardware/quirks/platforms/AMD64/010-dpms new file mode 100755 index 0000000000..a13917d3e5 --- /dev/null +++ b/packages/hardware/quirks/platforms/AMD64/010-dpms @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-dpms +DEVICE_SLEEP_DPMS="true" +EOF diff --git a/packages/hardware/quirks/platforms/AMD64/010-led_control b/packages/hardware/quirks/platforms/AMD64/010-led_control new file mode 100755 index 0000000000..905d0dbbe2 --- /dev/null +++ b/packages/hardware/quirks/platforms/AMD64/010-led_control @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +### Set the default device configuration +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="false" +DEVICE_LED_BRIGHTNESS="false" +EOF diff --git a/packages/hardware/quirks/platforms/AMD64/020-fan_control b/packages/hardware/quirks/platforms/AMD64/020-fan_control new file mode 100755 index 0000000000..eb4ddf9a9c --- /dev/null +++ b/packages/hardware/quirks/platforms/AMD64/020-fan_control @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/020-fan_control +DEVICE_HAS_FAN="false" +EOF diff --git a/packages/hardware/quirks/platforms/AMD64/sleep.d/post/001-dpms b/packages/hardware/quirks/platforms/AMD64/sleep.d/post/001-dpms new file mode 100755 index 0000000000..5a3e110885 --- /dev/null +++ b/packages/hardware/quirks/platforms/AMD64/sleep.d/post/001-dpms @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +if [ "${DEVICE_SLEEP_DPMS}" = "true" ] +then + dpms-client -m on & +fi diff --git a/packages/hardware/quirks/devices/AYANEO AYANEO 2S/sleep.d/post/001-dpms b/packages/hardware/quirks/platforms/AMD64/sleep.d/post/002-ledcontrol similarity index 54% rename from packages/hardware/quirks/devices/AYANEO AYANEO 2S/sleep.d/post/001-dpms rename to packages/hardware/quirks/platforms/AMD64/sleep.d/post/002-ledcontrol index 347ca4593b..7f7d042f97 100755 --- a/packages/hardware/quirks/devices/AYANEO AYANEO 2S/sleep.d/post/001-dpms +++ b/packages/hardware/quirks/platforms/AMD64/sleep.d/post/002-ledcontrol @@ -2,6 +2,9 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) -. /etc/profile +. /etc/profile.d/001-functions -dpms-client -m on +if [ "${DEVICE_LED_CONTROL}" = "true" ] +then + ledcontrol & +fi diff --git a/packages/hardware/quirks/devices/AYANEO AYANEO 2S/sleep.d/pre/001-dpms b/packages/hardware/quirks/platforms/AMD64/sleep.d/pre/001-dpms similarity index 53% rename from packages/hardware/quirks/devices/AYANEO AYANEO 2S/sleep.d/pre/001-dpms rename to packages/hardware/quirks/platforms/AMD64/sleep.d/pre/001-dpms index ad3d488f22..1da07fab7a 100755 --- a/packages/hardware/quirks/devices/AYANEO AYANEO 2S/sleep.d/pre/001-dpms +++ b/packages/hardware/quirks/platforms/AMD64/sleep.d/pre/001-dpms @@ -2,6 +2,9 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) -. /etc/profile +. /etc/profile.d/001-functions -dpms-client -m off +if [ "${DEVICE_SLEEP_DPMS}" = "true" ] +then + dpms-client -m off +fi diff --git a/packages/hardware/quirks/platforms/AMD64/sleep.d/pre/002-ledcontrol b/packages/hardware/quirks/platforms/AMD64/sleep.d/pre/002-ledcontrol new file mode 100755 index 0000000000..62a7282589 --- /dev/null +++ b/packages/hardware/quirks/platforms/AMD64/sleep.d/pre/002-ledcontrol @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions + +if [ "${DEVICE_LED_CONTROL}" = "true" ] +then + ledcontrol poweroff +fi diff --git a/packages/hardware/quirks/platforms/RK3326/002-turbo-mode_config b/packages/hardware/quirks/platforms/RK3326/002-turbo-mode_config new file mode 100644 index 0000000000..e78c24e2f7 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3326/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/packages/hardware/quirks/platforms/RK3399/002-turbo-mode_config b/packages/hardware/quirks/platforms/RK3399/002-turbo-mode_config new file mode 100644 index 0000000000..e78c24e2f7 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3399/002-turbo-mode_config @@ -0,0 +1,7 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-turbo-mode_config +DEVICE_TURBO_MODE="true" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566-X55 b/packages/hardware/quirks/platforms/RK3566-X55 deleted file mode 120000 index 9207b5754b..0000000000 --- a/packages/hardware/quirks/platforms/RK3566-X55 +++ /dev/null @@ -1 +0,0 @@ -RK3566 \ No newline at end of file diff --git a/packages/hardware/quirks/platforms/RK3566-X55/001-device_config b/packages/hardware/quirks/platforms/RK3566-X55/001-device_config new file mode 100755 index 0000000000..1647feaab3 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/001-device_config @@ -0,0 +1,10 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/001-device_config +DEVICE_FAKE_JACKSENSE="false" +DEVICE_VOLUMECTL="true" +DEVICE_POWER_LED="false" +DEVICE_BRIGHTNESS="128" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566-X55/050-audio_path b/packages/hardware/quirks/platforms/RK3566-X55/050-audio_path new file mode 100755 index 0000000000..5feee6024f --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/050-audio_path @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/002-audio_path +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_PLAYBACK_PATH="Playback Path" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566-X55/050-modifiers b/packages/hardware/quirks/platforms/RK3566-X55/050-modifiers new file mode 100755 index 0000000000..e135998332 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/050-modifiers @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/050-modifiers +DEVICE_KEY_VOLUMEDOWN=114 +DEVICE_KEY_VOLUMEUP=115 +DEVICE_FUNC_KEYA_MODIFIER="BTN_SELECT" +DEVICE_FUNC_KEYB_MODIFIER="BTN_MODE" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566-X55/060-game_settings b/packages/hardware/quirks/platforms/RK3566-X55/060-game_settings new file mode 100755 index 0000000000..23b4b938a7 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/060-game_settings @@ -0,0 +1,21 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile.d/001-functions +. /storage/.config/profile.d/010-governors + +### Set the minimum GPU frequency to reduce UI latency. +echo 400000000 >${GPU_FREQ}/min_freq + +### Set the default performance scaling mode for a few systems. +for SYSTEM in dreamcast n64 ports psp psx saturn gba pcfx cdi +do + SETTING=$(get_setting ${SYSTEM}) + if [ -z "${SETTING}" ] + then + set_setting ${SYSTEM}.cpugovernor performance + set_setting ${SYSTEM}.gpuperf profile_peak + fi +done + diff --git a/packages/hardware/quirks/platforms/RK3566-X55/090-ui_service b/packages/hardware/quirks/platforms/RK3566-X55/090-ui_service new file mode 100755 index 0000000000..accf1e59db --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/090-ui_service @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/090-ui_service +UI_SERVICE="emustation.service" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566-X55/091-ui_shader b/packages/hardware/quirks/platforms/RK3566-X55/091-ui_shader new file mode 100755 index 0000000000..7eab4389f5 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/091-ui_shader @@ -0,0 +1,8 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Set the default device configuration +cat </storage/.config/profile.d/091-ui_shader +UI_SHADER="glslp" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566-X55/sleep.d/post/002-freq b/packages/hardware/quirks/platforms/RK3566-X55/sleep.d/post/002-freq new file mode 100644 index 0000000000..d5c06cc41f --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/sleep.d/post/002-freq @@ -0,0 +1,23 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +### Restore previous governors before going to sleep + +. /etc/profile + +### Grab the old governors. +OLD_CPU_FREQ=$(get_setting "sleep.cpugovernor") +if [ ! -n "${OLD_CPU_FREQ}" ]; then + OLD_CPU_FREQ="schedutil" +fi + +OLD_GPU_FREQ=$(get_setting "sleep.gpugovernor") +if [ ! -n "${OLD_GPU_FREQ}" ]; then + OLD_GPU_FREQ="simple_ondemand" +fi + +# Restore old governors. +set_cpu_gov "${OLD_CPU_FREQ}" +set_dmc_gov "${OLD_CPU_FREQ}" +set_gpu_gov "${OLD_GPU_FREQ}" diff --git a/packages/hardware/quirks/platforms/RK3566-X55/sleep.d/pre/002-freq b/packages/hardware/quirks/platforms/RK3566-X55/sleep.d/pre/002-freq new file mode 100644 index 0000000000..4fbe8c64f0 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566-X55/sleep.d/pre/002-freq @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +# Store current freq governors and set governors to powersave. + +. /etc/profile + +### Get the current cpu and gpu governor, save for when the device wakes from sleep. +CUR_CPU_FREQ="$(cat ${CPU_FREQ}/scaling_governor)" +CUR_GPU_FREQ="$(cat ${GPU_FREQ}/governor)" + +set_setting sleep.cpugovernor "${CUR_CPU_FREQ}" +set_setting sleep.gpugovernor "${CUR_GPU_FREQ}" + +### Set all governors to powersave +set_cpu_gov powersave +set_dmc_gov powersave +set_gpu_gov powersave diff --git a/packages/hardware/quirks/platforms/RK3566/010-led_control b/packages/hardware/quirks/platforms/RK3566/010-led_control new file mode 100755 index 0000000000..fb09bb5511 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566/010-led_control @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +cat </storage/.config/profile.d/010-led_control +DEVICE_LED_CONTROL="true" +DEVICE_LED_BRIGHTNESS="false" +DEVICE_LED_CHARGING="true" +EOF diff --git a/packages/hardware/quirks/platforms/RK3566/060-game_settings b/packages/hardware/quirks/platforms/RK3566/060-game_settings index af5c03f7e8..23b4b938a7 100755 --- a/packages/hardware/quirks/platforms/RK3566/060-game_settings +++ b/packages/hardware/quirks/platforms/RK3566/060-game_settings @@ -3,12 +3,16 @@ # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) . /etc/profile.d/001-functions +. /storage/.config/profile.d/010-governors + +### Set the minimum GPU frequency to reduce UI latency. +echo 400000000 >${GPU_FREQ}/min_freq ### Set the default performance scaling mode for a few systems. -for SYSTEM in dreamcast n64 ports psp psx saturn gba +for SYSTEM in dreamcast n64 ports psp psx saturn gba pcfx cdi do SETTING=$(get_setting ${SYSTEM}) - if [ -z ${SETTING} ] + if [ -z "${SETTING}" ] then set_setting ${SYSTEM}.cpugovernor performance set_setting ${SYSTEM}.gpuperf profile_peak diff --git a/packages/hardware/quirks/platforms/RK3566/bin/ledcontrol b/packages/hardware/quirks/platforms/RK3566/bin/ledcontrol new file mode 100644 index 0000000000..fc301b6f89 --- /dev/null +++ b/packages/hardware/quirks/platforms/RK3566/bin/ledcontrol @@ -0,0 +1,72 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +. /etc/profile + +LED_PATH="/sys/class/leds" +LED_STATUS=$(get_setting led.color) + +function led_state() { + echo ${2} >${LED_PATH}/${1}/brightness +} + +function led_off() { + led_state battery_full 0 + led_state battery_charging 0 + led_state low_power 0 +} + +function led_red() { + led_off + led_state battery_charging 1 +} + +function led_green() { + led_off + led_state battery_full 1 +} + +case ${1} in + green) + led_green + set_setting led.color ${1} + ;; + red) + led_red + set_setting led.color ${1} + ;; + off) + led_off + set_setting led.color ${1} + ;; + discharging) + if [ -n "${LED_STATUS}" ] + then + ledcontrol ${LED_STATUS} + else + led_green + fi + ;; + charging) + if [ ! "${LED_STATUS}" = "off" ] + then + led_red + fi + ;; + default) + del_setting led.color + led_green + ;; + poweroff) + led_off + ;; + list) +cat </dev/null + umount /storage/roms 2>/dev/null ||: + umount /storage/games-external 2>/dev/null ||: cd / - find /storage -mindepth 1 \( ! -regex '^/storage/.update.*' -a ! -regex '^/storage/roms.*' -a ! -regex '^/storage/games-.*' \) -delete + find /storage -mindepth 1 \( ! -regex '^/storage/.update.*' -a ! -regex '^/storage/roms.*' -a ! -regex '^/storage/games-.*' \) -delete 2>/dev/null mkdir /storage/.config/ - sync + sync 2>/dev/null systemctl reboot ;; esac diff --git a/packages/jelos/sources/scripts/runemu.sh b/packages/jelos/sources/scripts/runemu.sh index 29127a1913..a755afed59 100755 --- a/packages/jelos/sources/scripts/runemu.sh +++ b/packages/jelos/sources/scripts/runemu.sh @@ -196,31 +196,9 @@ case ${EMULATOR} in ;; esac - RUNTHIS='${EMUPERF} /usr/bin/${RABIN} -L /tmp/cores/${CORE}_libretro.so --config ${RETROARCH_TEMP_CONFIG} --appendconfig ${RETROARCH_APPEND_CONFIG} "${ROMNAME}"' - - CONTROLLERCONFIG="${ARGUMENTS#*--controllers=*}" - - ### Configure our save state slot or autosave - CONTROLLERCONFIG="${CONTROLLERCONFIG%% --*}" # until a -- is found - SNAPSHOT="" - AUTOSAVE="" - case ${ARGUMENTS} in - *"-state_slot"*) - ${VERBOSE} && log $0 "Configuring save state slot." - CONTROLLERCONFIG="${CONTROLLERCONFIG%% -state_slot*}" # until -state is found - SNAPSHOT="${ARGUMENTS#*-state_slot *}" # -state_slot x - SNAPSHOT="${SNAPSHOT%% -*}" - ;; - *"-autosave"*) - ${VERBOSE} && log $0 "Configuring autosave." - CONTROLLERCONFIG="${CONTROLLERCONFIG%% -autosave*}" # until -autosave is found - AUTOSAVE="${ARGUMENTS#*-autosave *}" # -autosave x - AUTOSAVE="${AUTOSAVE%% -*}" - ;; - esac ### Configure specific emulator requirements - case ${EMULATOR} in + case ${CORE} in freej2me*) ${VERBOSE} && log $0 "Setup freej2me requirements." /usr/bin/freej2me.sh @@ -236,6 +214,29 @@ case ${EMULATOR} in ;; esac + + RUNTHIS='${EMUPERF} /usr/bin/${RABIN} -L /tmp/cores/${CORE}_libretro.so --config ${RETROARCH_TEMP_CONFIG} --appendconfig ${RETROARCH_APPEND_CONFIG} "${ROMNAME}"' + + CONTROLLERCONFIG="${ARGUMENTS#*--controllers=*}" + + if [[ "${ARGUMENTS}" == *"-state_slot"* ]] + then + CONTROLLERCONFIG="${CONTROLLERCONFIG%% -state_slot*}" # until -state is found + SNAPSHOT="${ARGUMENTS#*-state_slot *}" # -state_slot x + SNAPSHOT="${SNAPSHOT%% -*}" + if [[ "${ARGUMENTS}" == *"-autosave"* ]]; then + CONTROLLERCONFIG="${CONTROLLERCONFIG%% -autosave*}" # until -autosave is found + AUTOSAVE="${ARGUMENTS#*-autosave *}" # -autosave x + AUTOSAVE="${AUTOSAVE%% -*}" + else + AUTOSAVE="" + fi + else + CONTROLLERCONFIG="${CONTROLLERCONFIG%% --*}" # until a -- is found + SNAPSHOT="" + AUTOSAVE="" + fi + # Configure platform specific requirements case ${PLATFORM} in "atomiswave") diff --git a/packages/jelos/sources/scripts/setsettings.sh b/packages/jelos/sources/scripts/setsettings.sh index abf5362c05..9990c50cc9 100755 --- a/packages/jelos/sources/scripts/setsettings.sh +++ b/packages/jelos/sources/scripts/setsettings.sh @@ -32,9 +32,8 @@ CORE=${3,,} #Autosave AUTOSAVE="$@" -AUTOSAVE="${AUTOSAVE#*-autosave *}" +AUTOSAVE="${AUTOSAVE#*-autosave=*}" AUTOSAVE="${AUTOSAVE% --*}" -AUTOSAVE="${AUTOSAVE% --*}" # Fix later (first deletes --autosave, second deletes --snapshot). #Snapshot SNAPSHOT="$@" @@ -52,6 +51,7 @@ declare -a HAS_CHEEVOS=( arcade atari2600 atari7800 atarilynx + cdi colecovision cps1 cps2 diff --git a/packages/kernel/linux-firmware/RTL8723DS-firmware/firmware/rtl8723ds_config b/packages/kernel/linux-firmware/RTL8723DS-firmware/firmware/rtl8723ds_config new file mode 100644 index 0000000000..a08fa3a9f8 Binary files /dev/null and b/packages/kernel/linux-firmware/RTL8723DS-firmware/firmware/rtl8723ds_config differ diff --git a/packages/kernel/linux-firmware/RTL8723DS-firmware/firmware/rtl8723ds_fw b/packages/kernel/linux-firmware/RTL8723DS-firmware/firmware/rtl8723ds_fw new file mode 100644 index 0000000000..4c323a3d92 Binary files /dev/null and b/packages/kernel/linux-firmware/RTL8723DS-firmware/firmware/rtl8723ds_fw differ diff --git a/packages/kernel/linux-firmware/RTL8723DS-firmware/package.mk b/packages/kernel/linux-firmware/RTL8723DS-firmware/package.mk new file mode 100644 index 0000000000..585976a8f9 --- /dev/null +++ b/packages/kernel/linux-firmware/RTL8723DS-firmware/package.mk @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) + +PKG_NAME="RTL8723DS-firmware" +PKG_VERSION="" +PKG_LICENSE="Apache-2.0" +PKG_SITE="www.jelos.org" +PKG_LONGDESC="Realtek RTL8723DS Linux firmware" +PKG_DEPENDS_TARGET="linux rtk_hciattach" +PKG_TOOLCHAIN="manual" + +make_target() { + : +} + +makeinstall_target() { + mkdir -p ${INSTALL}/$(get_full_firmware_dir) ||: + cp -v ${PKG_DIR}/firmware/rtl8723ds_fw ${INSTALL}/$(get_full_firmware_dir)/rtl8723d_fw + cp -v ${PKG_DIR}/firmware/rtl8723ds_config ${INSTALL}/$(get_full_firmware_dir)/rtl8723d_config +} + diff --git a/packages/kernel/linux-firmware/kernel-firmware/package.mk b/packages/kernel/linux-firmware/kernel-firmware/package.mk index 794b5d98c0..e7f40b7813 100644 --- a/packages/kernel/linux-firmware/kernel-firmware/package.mk +++ b/packages/kernel/linux-firmware/kernel-firmware/package.mk @@ -2,10 +2,10 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="kernel-firmware" -PKG_VERSION="20231211" +PKG_VERSION="20240115" PKG_LICENSE="other" PKG_SITE="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/" -PKG_URL="https://cdn.kernel.org/pub/linux/kernel/firmware/linux-firmware-${PKG_VERSION}.tar.xz" +PKG_URL="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/snapshot/linux-firmware-${PKG_VERSION}.tar.gz" PKG_NEED_UNPACK="${PROJECT_DIR}/${PROJECT}/packages/${PKG_NAME} ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/packages/${PKG_NAME}" PKG_LONGDESC="kernel-firmware: kernel related firmware" PKG_TOOLCHAIN="manual" diff --git a/packages/kernel/linux/package.mk b/packages/kernel/linux/package.mk index 539c3c994b..e24266c107 100644 --- a/packages/kernel/linux/package.mk +++ b/packages/kernel/linux/package.mk @@ -4,7 +4,7 @@ PKG_NAME="linux" PKG_LICENSE="GPL" -PKG_VERSION="6.7.1" +PKG_VERSION="6.6.14" PKG_URL="https://www.kernel.org/pub/linux/kernel/v6.x/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_SITE="http://www.kernel.org" PKG_DEPENDS_HOST="ccache:host rsync:host openssl:host rdfind:host" diff --git a/packages/kernel/linux/patches/AMD64/002-LegionGO-rotation-quirk.patch b/packages/kernel/linux/patches/AMD64/002-LegionGO-rotation-quirk.patch index 1bca49a0a9..f4b8423eb7 100644 --- a/packages/kernel/linux/patches/AMD64/002-LegionGO-rotation-quirk.patch +++ b/packages/kernel/linux/patches/AMD64/002-LegionGO-rotation-quirk.patch @@ -1,533 +1,17 @@ -diff -rupN linux-6.7-rc8.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux-6.7-rc8.panel/drivers/gpu/drm/drm_panel_orientation_quirks.c ---- linux-6.7-rc8.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c 2024-01-04 23:15:09.706448784 +0000 -+++ linux-6.7-rc8.panel/drivers/gpu/drm/drm_panel_orientation_quirks.c 2024-01-04 23:20:09.071025713 +0000 +diff -rupN linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux/drivers/gpu/drm/drm_panel_orientation_quirks.c +--- linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-11-28 17:20:18.000000000 +0000 ++++ linux/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-11-30 15:33:54.949480402 +0000 @@ -336,6 +336,13 @@ static const struct dmi_system_id orient DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), }, .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Legion Go */ ++ }, { /* Lenovo Legion Go */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "83E1"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Legion Go 8APU1"), + }, + .driver_data = (void *)&lcd1600x2560_leftside_up, - }, { /* Lenovo Legion Go 8APU1 */ + }, { /* Lenovo Yoga Book X90F / X90L */ .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -diff -rupN linux-6.7-rc8.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c.orig linux-6.7-rc8.panel/drivers/gpu/drm/drm_panel_orientation_quirks.c.orig ---- linux-6.7-rc8.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c.orig 1970-01-01 00:00:00.000000000 +0000 -+++ linux-6.7-rc8.panel/drivers/gpu/drm/drm_panel_orientation_quirks.c.orig 2024-01-04 23:18:55.450922222 +0000 -@@ -0,0 +1,492 @@ -+/* SPDX-License-Identifier: MIT */ -+/* -+ * drm_panel_orientation_quirks.c -- Quirks for non-normal panel orientation -+ * -+ * Copyright (C) 2017 Hans de Goede -+ * -+ * Note the quirks in this file are shared with fbdev/efifb and as such -+ * must not depend on other drm code. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_DMI -+ -+/* -+ * Some x86 clamshell design devices use portrait tablet screens and a display -+ * engine which cannot rotate in hardware, so we need to rotate the fbcon to -+ * compensate. Unfortunately these (cheap) devices also typically have quite -+ * generic DMI data, so we match on a combination of DMI data, screen resolution -+ * and a list of known BIOS dates to avoid false positives. -+ */ -+ -+struct drm_dmi_panel_orientation_data { -+ int width; -+ int height; -+ const char * const *bios_dates; -+ int orientation; -+}; -+ -+static const struct drm_dmi_panel_orientation_data gpd_micropc = { -+ .width = 720, -+ .height = 1280, -+ .bios_dates = (const char * const []){ "04/26/2019", -+ NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data gpd_onemix2s = { -+ .width = 1200, -+ .height = 1920, -+ .bios_dates = (const char * const []){ "05/21/2018", "10/26/2018", -+ "03/04/2019", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data gpd_pocket = { -+ .width = 1200, -+ .height = 1920, -+ .bios_dates = (const char * const []){ "05/26/2017", "06/28/2017", -+ "07/05/2017", "08/07/2017", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data gpd_pocket2 = { -+ .width = 1200, -+ .height = 1920, -+ .bios_dates = (const char * const []){ "06/28/2018", "08/28/2018", -+ "12/07/2018", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data gpd_win = { -+ .width = 720, -+ .height = 1280, -+ .bios_dates = (const char * const []){ -+ "10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016", -+ "02/21/2017", "03/20/2017", "05/25/2017", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data gpd_win2 = { -+ .width = 720, -+ .height = 1280, -+ .bios_dates = (const char * const []){ -+ "12/07/2017", "05/24/2018", "06/29/2018", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data itworks_tw891 = { -+ .width = 800, -+ .height = 1280, -+ .bios_dates = (const char * const []){ "10/16/2015", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data onegx1_pro = { -+ .width = 1200, -+ .height = 1920, -+ .bios_dates = (const char * const []){ "12/17/2020", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = { -+ .width = 720, -+ .height = 1280, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd800x1280_leftside_up = { -+ .width = 800, -+ .height = 1280, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = { -+ .width = 800, -+ .height = 1280, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd1080x1920_leftside_up = { -+ .width = 1080, -+ .height = 1920, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = { -+ .width = 1200, -+ .height = 1920, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd1280x1920_rightside_up = { -+ .width = 1280, -+ .height = 1920, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd1600x2560_leftside_up = { -+ .width = 1600, -+ .height = 2560, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, -+}; -+ -+static const struct drm_dmi_panel_orientation_data lcd1600x2560_rightside_up = { -+ .width = 1600, -+ .height = 2560, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ -+static const struct dmi_system_id orientation_data[] = { -+ { /* Acer One 10 (S1003) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Acer Switch V 10 (SW5-017) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Anbernic Win600 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"), -+ }, -+ .driver_data = (void *)&lcd720x1280_rightside_up, -+ }, { /* Asus T100HA */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"), -+ }, -+ .driver_data = (void *)&lcd800x1280_leftside_up, -+ }, { /* Asus T101HA */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T101HA"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Asus T103HAF */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* AYA NEO 2021 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYADEVICE"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* AYA NEO AIR */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "AIR"), -+ }, -+ .driver_data = (void *)&lcd1080x1920_leftside_up, -+ }, { /* AYA NEO NEXT */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), -+ DMI_MATCH(DMI_BOARD_NAME, "NEXT"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Chuwi HiBook (CWI514) */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), -+ DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), -+ /* Above matches are too generic, add bios-date match */ -+ DMI_MATCH(DMI_BIOS_DATE, "05/07/2016"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Chuwi Hi10 Pro (CWI529) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Hampoo"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Hi10 pro tablet"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Dynabook K50 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dynabook Inc."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "dynabook K50/FR"), -+ }, -+ .driver_data = (void *)&lcd800x1280_leftside_up, -+ }, { /* GPD MicroPC (generic strings, also match on bios date) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_micropc, -+ }, { /* GPD MicroPC (later BIOS versions with proper DMI strings) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"), -+ }, -+ .driver_data = (void *)&lcd720x1280_rightside_up, -+ }, { /* GPD Win Max */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* -+ * GPD Pocket, note that the DMI data is less generic then -+ * it seems, devices with a board-vendor of "AMI Corporation" -+ * are quite rare, as are devices which have both board- *and* -+ * product-id set to "Default String" -+ */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_pocket, -+ }, { /* GPD Pocket 2 (generic strings, also match on bios date) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_pocket2, -+ }, { /* GPD Win (same note on DMI match as GPD Pocket) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_win, -+ }, { /* GPD Win 2 (too generic strings, also match on bios date) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_win2, -+ }, { /* GPD Win 3 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03") -+ }, -+ .driver_data = (void *)&lcd720x1280_rightside_up, -+ }, { /* I.T.Works TW891 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"), -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"), -+ }, -+ .driver_data = (void *)&itworks_tw891, -+ }, { /* KD Kurio Smart C15200 2-in-1 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "KD Interactive"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Kurio Smart"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "KDM960BCP"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* -+ * Lenovo Ideapad Miix 310 laptop, only some production batches -+ * have a portrait screen, the resolution checks makes the quirk -+ * apply only to those batches. -+ */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80SG"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Lenovo Ideapad Miix 320 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Lenovo Ideapad D330-10IGM (HD) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Lenovo Ideapad D330-10IGM (FHD) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Ideapad D330-10IGL (HD) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* Lenovo IdeaPad Duet 3 10IGL5 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Legion Go 8APU1 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Legion Go 8APU1"), -+ }, -+ .driver_data = (void *)&lcd1600x2560_leftside_up, -+ }, { /* Lenovo Yoga Book X90F / X90L */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Yoga Book X91F / X91L */ -+ .matches = { -+ /* Non exact match to match F + L versions */ -+ DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Yoga Tablet 2 830F / 830L */ -+ .matches = { -+ /* -+ * Note this also matches the Lenovo Yoga Tablet 2 1050F/L -+ * since that uses the same mainboard. The resolution match -+ * will limit this to only matching on the 830F/L. Neither has -+ * any external video outputs so those are not a concern. -+ */ -+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), -+ DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"), -+ /* Partial match on beginning of BIOS version */ -+ DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* Lenovo Yoga Tab 3 X90F */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), -+ }, -+ .driver_data = (void *)&lcd1600x2560_rightside_up, -+ }, { /* Nanote UMPC-01 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -+ }, { /* OneGX1 Pro */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), -+ }, -+ .driver_data = (void *)&onegx1_pro, -+ }, { /* OneXPlayer */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONE-NETBOOK TECHNOLOGY CO., LTD."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), -+ }, -+ .driver_data = (void *)&lcd1600x2560_leftside_up, -+ }, { /* Samsung GalaxyBook 10.6 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"), -+ }, -+ .driver_data = (void *)&lcd1280x1920_rightside_up, -+ }, { /* Valve Steam Deck */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* VIOS LTH17 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), -+ }, -+ .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* One Mix 2S (generic strings, also match on bios date) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_onemix2s, -+ }, -+ {} -+}; -+ -+/** -+ * drm_get_panel_orientation_quirk - Check for panel orientation quirks -+ * @width: width in pixels of the panel -+ * @height: height in pixels of the panel -+ * -+ * This function checks for platform specific (e.g. DMI based) quirks -+ * providing info on panel_orientation for systems where this cannot be -+ * probed from the hard-/firm-ware. To avoid false-positive this function -+ * takes the panel resolution as argument and checks that against the -+ * resolution expected by the quirk-table entry. -+ * -+ * Note this function is also used outside of the drm-subsys, by for example -+ * the efifb code. Because of this this function gets compiled into its own -+ * kernel-module when built as a module. -+ * -+ * Returns: -+ * A DRM_MODE_PANEL_ORIENTATION_* value if there is a quirk for this system, -+ * or DRM_MODE_PANEL_ORIENTATION_UNKNOWN if there is no quirk. -+ */ -+int drm_get_panel_orientation_quirk(int width, int height) -+{ -+ const struct dmi_system_id *match; -+ const struct drm_dmi_panel_orientation_data *data; -+ const char *bios_date; -+ int i; -+ -+ for (match = dmi_first_match(orientation_data); -+ match; -+ match = dmi_first_match(match + 1)) { -+ data = match->driver_data; -+ -+ if (data->width != width || -+ data->height != height) -+ continue; -+ -+ if (!data->bios_dates) -+ return data->orientation; -+ -+ bios_date = dmi_get_system_info(DMI_BIOS_DATE); -+ if (!bios_date) -+ continue; -+ -+ i = match_string(data->bios_dates, -1, bios_date); -+ if (i >= 0) -+ return data->orientation; -+ } -+ -+ return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; -+} -+EXPORT_SYMBOL(drm_get_panel_orientation_quirk); -+ -+#else -+ -+/* There are no quirks for non x86 devices yet */ -+int drm_get_panel_orientation_quirk(int width, int height) -+{ -+ return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; -+} -+EXPORT_SYMBOL(drm_get_panel_orientation_quirk); -+ -+#endif -+ -+MODULE_LICENSE("Dual MIT/GPL"); -diff -rupN linux-6.7-rc8.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c.rej linux-6.7-rc8.panel/drivers/gpu/drm/drm_panel_orientation_quirks.c.rej ---- linux-6.7-rc8.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c.rej 1970-01-01 00:00:00.000000000 +0000 -+++ linux-6.7-rc8.panel/drivers/gpu/drm/drm_panel_orientation_quirks.c.rej 2024-01-04 23:18:55.450922222 +0000 -@@ -0,0 +1,16 @@ -+--- drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-11-28 17:20:18.000000000 +0000 -++++ drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-11-30 15:33:54.949480402 +0000 -+@@ -336,6 +336,13 @@ static const struct dmi_system_id orient -+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), -+ }, -+ .driver_data = (void *)&lcd1200x1920_rightside_up, -++ }, { /* Lenovo Legion Go */ -++ .matches = { -++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), -++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "83E1"), -++ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Legion Go 8APU1"), -++ }, -++ .driver_data = (void *)&lcd1600x2560_leftside_up, -+ }, { /* Lenovo Yoga Book X90F / X90L */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), diff --git a/packages/kernel/linux/patches/AMD64/002-display-quirks.patch b/packages/kernel/linux/patches/AMD64/002-display-quirks.patch index 806f3f6449..7352a9946f 100755 --- a/packages/kernel/linux/patches/AMD64/002-display-quirks.patch +++ b/packages/kernel/linux/patches/AMD64/002-display-quirks.patch @@ -1,7 +1,7 @@ -diff -rupN linux-6.6.9.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux-6.6.9/drivers/gpu/drm/drm_panel_orientation_quirks.c ---- linux-6.6.9.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c 2024-01-04 00:22:05.545161814 +0000 -+++ linux-6.6.9/drivers/gpu/drm/drm_panel_orientation_quirks.c 2024-01-04 00:23:21.365247268 +0000 -@@ -141,6 +141,12 @@ static const struct drm_dmi_panel_orient +diff -rupN linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux/drivers/gpu/drm/drm_panel_orientation_quirks.c +--- linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-09-02 07:14:38.000000000 +0000 ++++ linux/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-09-09 03:24:49.178775423 +0000 +@@ -133,6 +133,12 @@ static const struct drm_dmi_panel_orient .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; @@ -14,7 +14,7 @@ diff -rupN linux-6.6.9.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux static const struct dmi_system_id orientation_data[] = { { /* Acer One 10 (S1003) */ .matches = { -@@ -178,13 +184,13 @@ static const struct dmi_system_id orient +@@ -170,13 +176,13 @@ static const struct dmi_system_id orient DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"), }, .driver_data = (void *)&lcd800x1280_rightside_up, @@ -31,7 +31,7 @@ diff -rupN linux-6.6.9.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), DMI_MATCH(DMI_PRODUCT_NAME, "AIR"), -@@ -196,6 +202,30 @@ static const struct dmi_system_id orient +@@ -188,6 +194,30 @@ static const struct dmi_system_id orient DMI_MATCH(DMI_BOARD_NAME, "NEXT"), }, .driver_data = (void *)&lcd800x1280_rightside_up, @@ -41,7 +41,7 @@ diff -rupN linux-6.6.9.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux + DMI_MATCH(DMI_BOARD_NAME, "GEEK"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* AYANEO AYANEO 2, 2S */ ++ }, { /* AYANEO AYANEO 2 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), + DMI_MATCH(DMI_PRODUCT_NAME, "AYANEO 2"), diff --git a/packages/kernel/linux/patches/AMD64/009-ayaneo-audio.patch b/packages/kernel/linux/patches/AMD64/009-ayaneo-audio.patch new file mode 100644 index 0000000000..d8ce9fe35e --- /dev/null +++ b/packages/kernel/linux/patches/AMD64/009-ayaneo-audio.patch @@ -0,0 +1,52 @@ +diff -rupN linux-6.7-rc8.orig/sound/pci/hda/patch_realtek.c linux-6.7-rc8.hda/sound/pci/hda/patch_realtek.c +--- linux-6.7-rc8.orig/sound/pci/hda/patch_realtek.c 2024-01-04 23:15:10.710503820 +0000 ++++ linux-6.7-rc8.hda/sound/pci/hda/patch_realtek.c 2024-01-04 23:23:29.598266931 +0000 +@@ -6550,6 +6550,20 @@ static void alc294_gx502_toggle_output(s + alc_write_coef_idx(codec, 0x10, 0x0a20); + } + ++static void alc269_fixup_headphone_volume(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ /* Pin 0x21: Some devices share 0x14 for headphones and speakers. ++ * This will fix ensure these devices have volume controls. */ ++ if (!is_jack_detectable(codec, 0x21)) ++ return; ++ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) { ++ static const hda_nid_t conn1[] = { 0x02 }; ++ snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1); ++ } ++} ++ + static void alc294_fixup_gx502_hp(struct hda_codec *codec, + const struct hda_fixup *fix, int action) + { +@@ -7235,6 +7249,7 @@ enum { + ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, + ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, + ALC269_FIXUP_DELL4_MIC_NO_PRESENCE_QUIET, ++ ALC269_FIXUP_HEADSET_AYANEO_DEVICES, + ALC269_FIXUP_HEADSET_MODE, + ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, + ALC269_FIXUP_ASPIRE_HEADSET_MIC, +@@ -8391,6 +8406,10 @@ static const struct hda_fixup alc269_fix + .chained = true, + .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE + }, ++ [ALC269_FIXUP_HEADSET_AYANEO_DEVICES] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc269_fixup_headphone_volume, ++ }, + [ALC256_FIXUP_ASUS_AIO_GPIO2] = { + .type = HDA_FIXUP_FUNC, + /* Set up GPIO2 for the speaker amp */ +@@ -10283,6 +10302,8 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1f66, 0x0101, "AYANEO Devices", ALC269_FIXUP_HEADSET_AYANEO_DEVICES), ++ SND_PCI_QUIRK(0x1f66, 0x0103, "AYANEO Air Plus", ALC269_FIXUP_HEADSET_AYANEO_DEVICES), + SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), + SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), + SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), diff --git a/packages/misc/modules/sources/fileman.sh b/packages/misc/modules/sources/fileman.sh index 9e9580c6a9..dccdc2847c 100755 --- a/packages/misc/modules/sources/fileman.sh +++ b/packages/misc/modules/sources/fileman.sh @@ -4,7 +4,11 @@ # Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) +gptokeyb fileman textinput & + . /etc/profile jslisten set "FileMan" fileman + +killall gptokeyb & diff --git a/packages/network/bluez/autostart/009-bluetooth b/packages/network/bluez/autostart/009-bluetooth index ebccc94d55..60fb5bd92d 100755 --- a/packages/network/bluez/autostart/009-bluetooth +++ b/packages/network/bluez/autostart/009-bluetooth @@ -7,6 +7,10 @@ if [ "$(get_setting bluetooth.enabled)" == "1" ] then tocon "Starting bluetooth..." + if [ ! -e "/storage/.cache/services/bluez.conf" ] + then + cp -f /usr/share/services/bluez.conf /storage/.cache/services/bluez.conf + fi nohup systemctl start bluetooth & nohup systemctl start bluetooth-agent & nohup systemctl start bluetoothsense & diff --git a/packages/network/bluez/package.mk b/packages/network/bluez/package.mk index 90d1a22b16..a738d5e17a 100644 --- a/packages/network/bluez/package.mk +++ b/packages/network/bluez/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) PKG_NAME="bluez" -PKG_VERSION="5.70" +PKG_VERSION="5.72" PKG_LICENSE="GPL" PKG_SITE="http://www.bluez.org/" PKG_URL="https://www.kernel.org/pub/linux/bluetooth/${PKG_NAME}-${PKG_VERSION}.tar.xz" @@ -71,9 +71,15 @@ post_makeinstall_target() { mkdir -p ${INSTALL}/etc/bluetooth cp src/main.conf ${INSTALL}/etc/bluetooth + cat <${INSTALL}/etc/bluetooth/input.conf +[General] +ClassicBondedOnly=false +EOF + mkdir -p ${INSTALL}/usr/share/services cp -P ${PKG_DIR}/default.d/*.conf ${INSTALL}/usr/share/services + # bluez looks in /etc/firmware/ ln -sf /usr/lib/firmware ${INSTALL}/etc/firmware diff --git a/packages/sysutils/busybox/scripts/fs-resize b/packages/sysutils/busybox/scripts/fs-resize index f348ffe5ee..4f3d941fba 100755 --- a/packages/sysutils/busybox/scripts/fs-resize +++ b/packages/sysutils/busybox/scripts/fs-resize @@ -22,7 +22,7 @@ if [ -e /storage/.please_resize_me ] ; then # get the disk. /storage on 2nd partition PART=$(blkid | awk 'BEGIN {FS=":"} /'$(cat /proc/cmdline | sed -e 's#^.*disk=UUID=##g' -e 's#\ .*$##g')'/ {print $1}') - if [ "$(echo ${PART} | awk '/mmcblk/ {print $1}')" ] + if [ "$(echo ${PART} | awk '/mmcblk/ || /nvme/ {print $1}')" ] then DISK=$(echo ${PART} | sed s/p[0-9]//g) PARTNUM=$(echo ${PART} | sed "s#^.*[0-9]p##g") diff --git a/packages/sysutils/powerstate/sources/powerstate.sh b/packages/sysutils/powerstate/sources/powerstate.sh index a4e11974fe..e28605db58 100755 --- a/packages/sysutils/powerstate/sources/powerstate.sh +++ b/packages/sysutils/powerstate/sources/powerstate.sh @@ -13,6 +13,8 @@ BATCNT=0 unset CURRENT_MODE unset AC_STATUS +ledcontrol $(get_setting led.color) + while true do AC_STATUS="$(cat /sys/class/power_supply/[bB][aA][tT]*/status 2>/dev/null)" @@ -41,6 +43,10 @@ do runtime_power_management auto 5 scsi_link_power_management med_power_with_dipm fi + if [ "${DEVICE_LED_CHARGING}" = "true" ] + then + ledcontrol discharging + fi ;; *) if [ "$(get_setting system.powersave)" = 1 ] @@ -54,22 +60,26 @@ do runtime_power_management on 0 scsi_link_power_management "" fi + if [ "${DEVICE_LED_CHARGING}" = "true" ] + then + ledcontrol charging + fi ;; esac /usr/bin/wifictl setpowersave - ledcontrol $(get_setting led.color) CURRENT_MODE="${AC_STATUS}" fi ### Until we have an overlay. :rofl: + BATLEFT=$(battery_percent) if (( "${BATCNT}" >= "90" )) && [[ "${STATUS}" =~ Disch ]] then - BATLEFT=$(battery_percent) AUDIBLEALERT=$(get_setting system.battery.warning) - if (( "${BATLEFT}" < "25" )) + if (( ${BATLEFT} < "26" )) then if [ "${DEVICE_LED_CONTROL}" = "true" ] then + # Flash the RGB or power LED if available. led_flash red BATCNT=0 elif [ "${AUDIBLEALERT}" = "1" ] @@ -78,6 +88,13 @@ do BATCNT=0 fi fi + elif (( "${BATLEFT}" > "97" )) + then + if [ "${DEVICE_LED_CHARGING}" = "true" ] + then + # Reset the LED as if the battery was full. + ledcontrol discharging + fi fi BATCNT=$(( ${BATCNT} + 1 )) sleep 2 diff --git a/packages/sysutils/stress-ng/package.mk b/packages/sysutils/stress-ng/package.mk index 5bf19d27f6..2a3e2b9d46 100644 --- a/packages/sysutils/stress-ng/package.mk +++ b/packages/sysutils/stress-ng/package.mk @@ -1,11 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) PKG_NAME="stress-ng" -PKG_VERSION="0.09.50" -PKG_SHA256="b07290495794092cdf2f8d51ac631f28b8cec9455a16552d8ca48bc1f376c634" +PKG_VERSION="2f22ad595f067aa940cfe4f64107e10872c2f7b5" # V0.17.04 PKG_LICENSE="GPLv2" -PKG_SITE="http://kernel.ubuntu.com/~cking/stress-ng/" -PKG_URL="http://kernel.ubuntu.com/~cking/tarballs/stress-ng/stress-ng-${PKG_VERSION}.tar.xz" -PKG_DEPENDS_TARGET="toolchain attr keyutils libaio libcap zlib" +PKG_SITE="https://github.com/ColinIanKing/stress-ng" +PKG_URL="${PKG_SITE}.git" +GET_HANDLER_SUPPORT="git" +PKG_DEPENDS_TARGET="toolchain attr keyutils libaio libcap zlib libjpeg-turbo" PKG_LONGDESC="stress-ng will stress test a computer system in various selectable ways" +PKG_TOOLCHAIN="make" diff --git a/packages/sysutils/system-utils/package.mk b/packages/sysutils/system-utils/package.mk index a1baf0744e..7bf26a40ec 100644 --- a/packages/sysutils/system-utils/package.mk +++ b/packages/sysutils/system-utils/package.mk @@ -22,6 +22,7 @@ makeinstall_target() { cp ${PKG_DIR}/sources/scripts/volume_sense ${INSTALL}/usr/bin cp ${PKG_DIR}/sources/scripts/bluetooth_sense ${INSTALL}/usr/bin cp ${PKG_DIR}/sources/scripts/ledcontrol ${INSTALL}/usr/bin + cp ${PKG_DIR}/sources/scripts/turbomode ${INSTALL}/usr/bin if [ -d "${PKG_DIR}/sources/devices/${DEVICE}" ] then cp ${PKG_DIR}/sources/devices/${DEVICE}/* ${INSTALL}/usr/bin diff --git a/packages/sysutils/system-utils/sources/devices/RK3326/battery_led_status b/packages/sysutils/system-utils/sources/devices/RK3326/battery_led_status index 62a55e16ca..7d16d49b05 100644 --- a/packages/sysutils/system-utils/sources/devices/RK3326/battery_led_status +++ b/packages/sysutils/system-utils/sources/devices/RK3326/battery_led_status @@ -8,14 +8,9 @@ . /etc/profile -# Set export GPIO for Power LED -if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then - echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export -fi - function set_led() { case $1 in - red) + red|off) echo out >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/direction echo 1 >/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}/value ;; @@ -29,36 +24,52 @@ function set_led() { esac } +#Redirect to the device quirks version if it is there +if [ -f "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/battery_led_status" ] +then + "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/battery_led_status" $* +else + # Set export GPIO for Power LED + if [ ! -d "/sys/class/gpio/gpio${DEVICE_PWR_LED_GPIO}" ]; then + echo ${DEVICE_PWR_LED_GPIO} > /sys/class/gpio/export + fi -while true -do - CAP=$(cat /sys/class/power_supply/battery/capacity) - STAT=$(cat /sys/class/power_supply/battery/status) - if [[ ${STAT} == "Discharging" ]] - then - #if (( ${CAP} <= 50 )) - #then - # for ctr in $(seq 1 1 5) - # do - # set_led orange - # sleep .5 - # set_led red - # sleep .5 - # done - # continue - #elif (( ${CAP} <= 20 )) - if (( ${CAP} <= 20 )) + while true + do + CAP=$(cat /sys/class/power_supply/battery/capacity) + STAT=$(cat /sys/class/power_supply/battery/status) + ISDISABLED=$(get_setting powerled.disabled) + if [ "${ISDISABLED}" == "1" ] then - set_led red - elif (( ${CAP} <= 30 )) - then - set_led orange + set_led off else - set_led green + if [[ ${STAT} == "Discharging" ]] + then + #if (( ${CAP} <= 50 )) + #then + # for ctr in $(seq 1 1 5) + # do + # set_led orange + # sleep .5 + # set_led red + # sleep .5 + # done + # continue + #elif (( ${CAP} <= 20 )) + if (( ${CAP} <= 20 )) + then + set_led red + elif (( ${CAP} <= 30 )) + then + set_led orange + else + set_led green + fi + elif (( ${CAP} >= 95 )) + then + set_led green + fi + sleep 15 fi - elif (( ${CAP} >= 95 )) - then - set_led green - fi - sleep 15 -done + done +fi diff --git a/packages/sysutils/system-utils/sources/scripts/ledcontrol b/packages/sysutils/system-utils/sources/scripts/ledcontrol index 28be166eb1..44d5a9fffe 100755 --- a/packages/sysutils/system-utils/sources/scripts/ledcontrol +++ b/packages/sysutils/system-utils/sources/scripts/ledcontrol @@ -3,10 +3,16 @@ # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) ### -### LED Control now redirects to the quirk device/bin/ledcontrol +### LED Control now redirects to the quirk device or platform /bin/ledcontrol ### so we don't need to have multiple variants in /usr/bin. ### . /etc/profile -"/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/ledcontrol" $* +if [ -f "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/ledcontrol" ] +then + "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/bin/ledcontrol" $* +elif [ -f "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/bin/ledcontrol" ] +then + "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/bin/ledcontrol" $* +fi diff --git a/packages/sysutils/system-utils/sources/scripts/turbomode b/packages/sysutils/system-utils/sources/scripts/turbomode new file mode 100644 index 0000000000..0eeee9388b --- /dev/null +++ b/packages/sysutils/system-utils/sources/scripts/turbomode @@ -0,0 +1,15 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2024 JELOS (https://github.com/JustEnoughLinuxOS) + +# Set turbomode state +case $1 in + disable) + echo "0" > /sys/devices/system/cpu/cpufreq/boost + set_setting enable.turbo-mode 0 + ;; + enable) + echo "1" > /sys/devices/system/cpu/cpufreq/boost + set_setting enable.turbo-mode 1 + ;; +esac diff --git a/packages/themes/es-theme-art-book-next/package.mk b/packages/themes/es-theme-art-book-next/package.mk index 5e38e44d1b..3cec273c27 100644 --- a/packages/themes/es-theme-art-book-next/package.mk +++ b/packages/themes/es-theme-art-book-next/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) PKG_NAME="es-theme-art-book-next" -PKG_VERSION="b88d2b3d31d9cbfdd68be405dcf41ace924be950" +PKG_VERSION="6b2b77d65ab467e4e27343dfbf17ea07596ded90" PKG_ARCH="any" PKG_LICENSE="CUSTOM" PKG_SITE="https://github.com/anthonycaccese/art-book-next-jelos" diff --git a/packages/ui/emulationstation/config/common/es_features.cfg b/packages/ui/emulationstation/config/common/es_features.cfg index f0cb3b9e39..3b3e939df0 100644 --- a/packages/ui/emulationstation/config/common/es_features.cfg +++ b/packages/ui/emulationstation/config/common/es_features.cfg @@ -779,6 +779,7 @@ + @@ -899,7 +900,8 @@ - = + + diff --git a/packages/ui/emulationstation/config/common/es_input.cfg b/packages/ui/emulationstation/config/common/es_input.cfg index 9e2b83d4de..e379e387ff 100644 --- a/packages/ui/emulationstation/config/common/es_input.cfg +++ b/packages/ui/emulationstation/config/common/es_input.cfg @@ -1294,4 +1294,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/emulationstation/package.mk b/packages/ui/emulationstation/package.mk index ba2b55005b..624bd3926c 100644 --- a/packages/ui/emulationstation/package.mk +++ b/packages/ui/emulationstation/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS) PKG_NAME="emulationstation" -PKG_VERSION="ba5c0f88a21fdd19fe0b0f94e1ff6229fbf682cf" +PKG_VERSION="b298647ee7988cf2a34fedd4442f357f63c66597" PKG_GIT_CLONE_BRANCH="main" PKG_REV="1" PKG_ARCH="any" diff --git a/packages/ui/emulationstation/system.d/emustation.service b/packages/ui/emulationstation/system.d/emustation.service index 158686aa3c..1e5e1fbe0a 100644 --- a/packages/ui/emulationstation/system.d/emustation.service +++ b/packages/ui/emulationstation/system.d/emustation.service @@ -7,9 +7,7 @@ After=jelos-automount.service Environment=XDG_RUNTIME_DIR=/var/run/0-runtime-dir Environment=HOME=/storage Environment=SDL_AUDIODRIVER=pulseaudio -ExecStartPre=/usr/bin/es_settings -ExecStart=/usr/bin/emulationstation --log-path /var/log --no-splash -KillMode=process +ExecStart=/usr/bin/start_es.sh TimeoutStopSec=3 Restart=always RestartSec=2 diff --git a/packages/virtual/emulators/package.mk b/packages/virtual/emulators/package.mk index 642f64c338..5ba027f058 100644 --- a/packages/virtual/emulators/package.mk +++ b/packages/virtual/emulators/package.mk @@ -17,13 +17,13 @@ PKG_RETROARCH="core-info libretro-database retroarch retroarch-assets retroarch- LIBRETRO_CORES="81-lr a5200-lr arduous-lr atari800-lr beetle-gba-lr beetle-lynx-lr beetle-ngp-lr beetle-pce-lr beetle-pce-fast-lr \ beetle-pcfx-lr bsnes-mercury-performance-lr beetle-supafaust-lr beetle-supergrafx-lr \ beetle-vb-lr beetle-wswan-lr bluemsx-lr cap32-lr crocods-lr daphne-lr \ - dosbox-svn-lr dosbox-pure-lr duckstation-lr easyrpg-lr fake08-lr fbalpha2012-lr \ + dosbox-svn-lr dosbox-pure-lr duckstation-lr easyrpg-lr emuscv-lr fake08-lr fbalpha2012-lr \ fbalpha2019-lr fbneo-lr fceumm-lr flycast2021-lr fmsx-lr freechaf-lr freeintv-lr freej2me-lr fuse-lr \ gambatte-lr gearboy-lr gearcoleco-lr gearsystem-lr genesis-plus-gx-lr genesis-plus-gx-wide-lr \ gw-lr handy-lr hatari-lr idtech-lr mame-lr mame2003-plus-lr mame2010-lr mame2015-lr melonds-lr \ mesen-lr mgba-lr mojozork-lr mupen64plus-lr mupen64plus-nx-lr neocd_lr nestopia-lr np2kai-lr \ o2em-lr opera-lr parallel-n64-lr pcsx_rearmed-lr picodrive-lr pokemini-lr potator-lr \ - prosystem-lr puae-lr puae2021-lr px68k-lr quasi88-lr quicknes-lr race-lr \ + prosystem-lr puae-lr puae2021-lr px68k-lr quasi88-lr quicknes-lr race-lr same_cdi-lr \ sameboy-lr sameduck-lr scummvm-lr smsplus-gx-lr snes9x-lr snes9x2002-lr snes9x2005_plus-lr snes9x2010-lr \ stella-lr swanstation-lr tic80-lr tgbdual-lr uzem-lr vba-next-lr minivmac-lr \ vbam-lr vecx-lr vice-lr yabasanshiro-lr virtualjaguar-lr xmil-lr" @@ -38,7 +38,7 @@ case "${DEVICE}" in ppsspp-lr kronos-lr beetle-saturn-lr" ;; RK358*) - [ "${ENABLE_32BIT}" == "true" ] && EMUS_32BIT="box86 desmume-lr flycast-lr gpsp-lr pcsx_rearmed-lr" + [ "${ENABLE_32BIT}" == "true" ] && EMUS_32BIT="box86 desmume-lr gpsp-lr pcsx_rearmed-lr" PKG_EMUS+=" amiberry aethersx2-sa dolphin-sa drastic-sa duckstation-sa melonds-sa nanoboyadvance-sa box64 scummvmsa \ yabasanshiro-sa portmaster beetle-saturn-lr" LIBRETRO_CORES+=" uae4arm beetle-psx-lr bsnes-lr bsnes-hd-lr citra-lr dolphin-lr pcsx_rearmed-lr" @@ -59,7 +59,7 @@ case "${DEVICE}" in PKG_RETROARCH+=" retropie-shaders" ;; S922X*) - [ "${ENABLE_32BIT}" == "true" ] && EMUS_32BIT="box86 flycast-lr pcsx_rearmed-lr" + [ "${ENABLE_32BIT}" == "true" ] && EMUS_32BIT="box86 pcsx_rearmed-lr" PKG_EMUS+=" amiberry aethersx2-sa citra-sa dolphin-sa duckstation-sa drastic-sa mupen64plus-sa yabasanshiro-sa \ box64 portmaster" LIBRETRO_CORES+=" uae4arm beetle-psx-lr bsnes-lr bsnes-hd-lr dolphin-lr flycast-lr" @@ -69,7 +69,7 @@ case "${DEVICE}" in [ "${ENABLE_32BIT}" == "true" ] && EMUS_32BIT="desmume-lr gpsp-lr pcsx_rearmed-lr" PKG_DEPENDS_TARGET+=" common-shaders glsl-shaders" PKG_EMUS+=" amiberry drastic-sa mupen64plus-sa scummvmsa yabasanshiro-sa portmaster mednafen" - LIBRETRO_CORES+=" uae4arm flycast-lr" + LIBRETRO_CORES+=" uae4arm flycast-lr flycast2021-lr" PKG_RETROARCH+=" retropie-shaders" ;; esac @@ -224,6 +224,7 @@ makeinstall_target() { add_emu_core atomiswave flycast flycast-sa false ;; RK33*) + add_emu_core atomiswave retroarch flycast2021 false add_emu_core atomiswave flycast flycast-sa false add_emu_core atomiswave retroarch flycast true ;; @@ -322,6 +323,7 @@ makeinstall_target() { add_emu_core dreamcast flycast flycast-sa false ;; RK33*) + add_emu_core dreamcast retroarch flycast2021 false add_emu_core dreamcast flycast flycast-sa false add_emu_core dreamcast retroarch flycast true ;; @@ -635,6 +637,7 @@ makeinstall_target() { add_emu_core naomi flycast flycast-sa false ;; RK33*) + add_emu_core naomi retroarch flycast2021 false add_emu_core naomi flycast flycast-sa false add_emu_core naomi retroarch flycast true ;; @@ -1165,6 +1168,10 @@ makeinstall_target() { add_emu_core vectrex retroarch vecx true add_es_system vectrex + ### Philips - CDi + add_emu_core cdi retroarch same_cdi true + add_es_system cdi + ### Philips Videopac add_emu_core videopac retroarch o2em true add_es_system videopac @@ -1200,6 +1207,10 @@ makeinstall_target() { add_emu_core x68000 retroarch px68k true add_es_system x68000 + ### EPOCH/YENO Super Cassette Vision + add_emu_core scv retroarch emuscv true + add_es_system scv + ### PC Ports case ${TARGET_ARCH} in arm|aarch64) diff --git a/packages/wayland/weston/patches/003-use-old-repaint-behavior.patch b/packages/wayland/weston/patches/003-use-old-repaint-behavior.patch index 6d7bafbe29..a9c0af1b54 100644 --- a/packages/wayland/weston/patches/003-use-old-repaint-behavior.patch +++ b/packages/wayland/weston/patches/003-use-old-repaint-behavior.patch @@ -1,19 +1,12 @@ diff -rupN weston-12.0.3.orig/libweston/compositor.c weston-12.0.3/libweston/compositor.c --- weston-12.0.3.orig/libweston/compositor.c 2024-01-15 15:42:23.723505677 +0000 -+++ weston-12.0.3/libweston/compositor.c 2024-01-20 13:27:54.816568920 +0000 -@@ -3349,10 +3349,13 @@ weston_output_finish_frame(struct weston - * If timestamp of latest vblank is given, it must always go forwards. ++++ weston-12.0.3/libweston/compositor.c 2024-01-24 00:32:15.715324559 +0000 +@@ -3350,7 +3350,7 @@ weston_output_finish_frame(struct weston * If not given, INVALID flag must be set. */ -- if (stamp) -+ /* if (stamp) - assert(timespec_sub_to_nsec(stamp, &output->frame_time) >= 0); + if (stamp) +- assert(timespec_sub_to_nsec(stamp, &output->frame_time) >= 0); ++ assert(timespec_sub_to_nsec(stamp, &output->frame_time) || (presented_flags & WP_PRESENTATION_FEEDBACK_INVALID)); else -- assert(presented_flags & WP_PRESENTATION_FEEDBACK_INVALID); -+ assert(presented_flags & WP_PRESENTATION_FEEDBACK_INVALID); */ -+ -+ assert(output->repaint_status == REPAINT_AWAITING_COMPLETION); -+ assert(stamp || (presented_flags & WP_PRESENTATION_FEEDBACK_INVALID)); - - weston_compositor_read_presentation_clock(compositor, &now); + assert(presented_flags & WP_PRESENTATION_FEEDBACK_INVALID); diff --git a/projects/Amlogic/bootloader/mkimage b/projects/Amlogic/bootloader/mkimage index 60b98373c0..9362cc1939 100644 --- a/projects/Amlogic/bootloader/mkimage +++ b/projects/Amlogic/bootloader/mkimage @@ -44,7 +44,7 @@ mkimage_gou_extras() { case "${SUBDEVICE}" in Odroid_GOU) - DTB=("meson-g12b-odroid-go-ultra" "meson-g12b-powkiddy-rgb10-max-3") + DTB=("meson-g12b-odroid-go-ultra" "meson-g12b-powkiddy-rgb10-max-3-pro") mkimage_dtb mkimage_bootini mkimage_gou_extras diff --git a/projects/Amlogic/bootloader/update.sh b/projects/Amlogic/bootloader/update.sh index 9f08f0cf18..4f156d612a 100755 --- a/projects/Amlogic/bootloader/update.sh +++ b/projects/Amlogic/bootloader/update.sh @@ -66,7 +66,7 @@ DT_ID=$($SYSTEM_ROOT/usr/bin/dtname) if [ -n "$DT_ID" ]; then case $DT_ID in - *odroid_go_ultra*|*rgb10-max-3*) + *odroid-go-ultra*|*rgb10-max-3*) SUBDEVICE="Odroid_GOU" ;; *odroid-n2|*odroid-n2-plus) @@ -78,6 +78,9 @@ if [ -n "$DT_ID" ]; then esac fi +# Rename RGB10 Max 3 device tree after buildroot changes, remove this in the future +[ -f $BOOT_ROOT/meson-g12b-powkiddy-rgb10-max-3.dtb ] && mv $BOOT_ROOT/meson-g12b-powkiddy-rgb10-max-3.dtb $BOOT_ROOT/meson-g12b-powkiddy-rgb10-max-3-pro.dtb + for all_dtb in $BOOT_ROOT/*.dtb; do dtb=$(basename $all_dtb) if [ -f $SYSTEM_ROOT/usr/share/bootloader/$dtb ]; then @@ -113,6 +116,10 @@ fi if [ -f $SYSTEM_ROOT/usr/share/bootloader/${SUBDEVICE}_u-boot ]; then echo "Updating u-boot on: $BOOT_DISK..." dd if=$SYSTEM_ROOT/usr/share/bootloader/${SUBDEVICE}_u-boot of=$BOOT_DISK conv=fsync,notrunc bs=512 seek=1 &>/dev/null + if [ $BOOT_DISK != /dev/mmcblk0 ]; then + echo "Updating u-boot on: /dev/mmcblk0..." + dd if=$SYSTEM_ROOT/usr/share/bootloader/${SUBDEVICE}_u-boot of=/dev/mmcblk0 conv=fsync,notrunc bs=512 seek=1 &>/dev/null + fi fi if [ -f $BOOT_ROOT/ODROIDBIOS.BIN ]; then diff --git a/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch b/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-Pro-device-tree.patch similarity index 78% rename from projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch rename to projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-Pro-device-tree.patch index 907dfcf029..27121f42fa 100644 --- a/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch +++ b/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-Pro-device-tree.patch @@ -1,8 +1,8 @@ -diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3-pro.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3-pro.dts new file mode 100644 index 000000000000..df5dde6eec79 --- /dev/null -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3-pro.dts @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* @@ -14,8 +14,8 @@ index 000000000000..df5dde6eec79 +#include "meson-g12b-odroid-go-ultra.dts" + +/ { -+ compatible = "powkiddy,rgb10-max-3", "amlogic,a311d", "amlogic,g12b"; -+ model = "Powkiddy RGB10 MAX 3"; ++ compatible = "powkiddy,rgb10-max-3-pro", "amlogic,a311d", "amlogic,g12b"; ++ model = "Powkiddy RGB10 MAX 3 Pro"; + + /delete-node/ hp-detect-switch; + @@ -40,6 +40,6 @@ index 000000000000..df5dde6eec79 + }; + + sound { -+ model = "RGB10-MAX3"; ++ model = "RGB10-MAX-3-PRO"; + }; +}; diff --git a/projects/Amlogic/packages/u-boot-Odroid_GOU/patches/001-multiboot.patch b/projects/Amlogic/packages/u-boot-Odroid_GOU/patches/001-multiboot.patch index 3c0e4f231e..3ba7fd8798 100644 --- a/projects/Amlogic/packages/u-boot-Odroid_GOU/patches/001-multiboot.patch +++ b/projects/Amlogic/packages/u-boot-Odroid_GOU/patches/001-multiboot.patch @@ -27,7 +27,7 @@ index d08f0aac00..a9c6a13279 100755 + setenv("fdtfile", "meson-g12b-odroid-go-ultra.dtb"); + } else { + setenv("variant", "max3"); -+ setenv("fdtfile", "meson-g12b-powkiddy-rgb10-max-3.dtb"); ++ setenv("fdtfile", "meson-g12b-powkiddy-rgb10-max-3-pro.dtb"); + } + + // board_set_dtbfile("meson64_odroid%s.dtb"); diff --git a/projects/Rockchip/devices/RK3326/boot/boot.ini b/projects/Rockchip/devices/RK3326/boot/boot.ini index f65059adc9..4438411643 100644 --- a/projects/Rockchip/devices/RK3326/boot/boot.ini +++ b/projects/Rockchip/devices/RK3326/boot/boot.ini @@ -23,8 +23,12 @@ elif test ${hwrev} = 'v10'; then load mmc 1:1 ${dtb_loadaddr} rk3326-odroid-go2.dtb elif test ${hwrev} = 'rg351v'; then load mmc 1:1 ${dtb_loadaddr} rk3326-anbernic-rg351v.dtb -elif test ${hwrev} = 'rg351mp'; then - load mmc 1:1 ${dtb_loadaddr} rk3326-anbernic-rg351mp.dtb +elif test ${hwrev} = 'r33s'; then +# if gpio input 11; then +# load mmc 1:1 ${dtb_loadaddr} rk3326-powkiddy-rgb20s.dtb +# else + load mmc 1:1 ${dtb_loadaddr} rk3326-gameconsole-r33s.dtb +# fi elif test ${hwrev} = 'xu10'; then load mmc 1:1 ${dtb_loadaddr} rk3326-magicx-xu10.dtb fi diff --git a/projects/Rockchip/devices/RK3326/filesystem/etc/interception/oga-controls.yaml b/projects/Rockchip/devices/RK3326/filesystem/etc/interception/oga-controls.yaml deleted file mode 100755 index 6b9de5eb6a..0000000000 --- a/projects/Rockchip/devices/RK3326/filesystem/etc/interception/oga-controls.yaml +++ /dev/null @@ -1,19 +0,0 @@ -NAME: GO-Advance Gamepad Virtual -PRODUCT: 0x1000 -VENDOR: 0x484B -BUSTYPE: BUS_HOST -DRIVER_VERSION: 0x0100 -EVENTS: - EV_SYN: [SYN_REPORT, SYN_CONFIG, SYN_MT_REPORT, SYN_DROPPED] - EV_KEY: [BTN_SOUTH, BTN_EAST, BTN_NORTH, BTN_WEST, BTN_TL, BTN_TR, BTN_DPAD_UP, BTN_DPAD_DOWN, BTN_DPAD_LEFT, BTN_DPAD_RIGHT, BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, BTN_TRIGGER_HAPPY5, BTN_TRIGGER_HAPPY6] - EV_ABS: - ABS_X: - MIN: 172 - MAX: 772 - FLAT: 10 - FUZZ: 10 - ABS_Y: - MIN: 278 - MAX: 815 - FLAT: 10 - FUZZ: 10 diff --git a/projects/Rockchip/devices/RK3326/filesystem/etc/interception/udevmon.yaml b/projects/Rockchip/devices/RK3326/filesystem/etc/interception/udevmon.yaml deleted file mode 100755 index 478329fd76..0000000000 --- a/projects/Rockchip/devices/RK3326/filesystem/etc/interception/udevmon.yaml +++ /dev/null @@ -1,8 +0,0 @@ -- CMD: mux -c oga-control -- JOB: mux -i oga-control | uinput -c /etc/interception/oga-controls.yaml -- JOB: intercept -g $DEVNODE | mux -o oga-control - DEVICE: - LINK: /dev/input/by-path/platform-adc-joystick-event -- JOB: intercept -g $DEVNODE | mux -o oga-control - DEVICE: - LINK: /dev/input/by-path/platform-gpio-keys-event-joystick diff --git a/projects/Rockchip/devices/RK3326/filesystem/usr/lib/systemd/system/udevmon.service b/projects/Rockchip/devices/RK3326/filesystem/usr/lib/systemd/system/udevmon.service deleted file mode 100644 index d209dda2c8..0000000000 --- a/projects/Rockchip/devices/RK3326/filesystem/usr/lib/systemd/system/udevmon.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Monitor input devices for launching tasks -Wants=systemd-udev-settle.service -After=systemd-udev-settle.service -Documentation=man:udev(7) - -[Service] -ExecStart=/usr/bin/udevmon -c /etc/interception/udevmon.yaml -Nice=-20 -Restart=on-failure -OOMScoreAdjust=-1000 - -[Install] -WantedBy=multi-user.target diff --git a/projects/Rockchip/devices/RK3326/linux/linux.aarch64.conf b/projects/Rockchip/devices/RK3326/linux/linux.aarch64.conf index 130fed1509..08bf4eeedb 100644 --- a/projects/Rockchip/devices/RK3326/linux/linux.aarch64.conf +++ b/projects/Rockchip/devices/RK3326/linux/linux.aarch64.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 6.7.0 Kernel Configuration +# Linux/arm64 6.7.2 Kernel Configuration # CONFIG_CC_VERSION_TEXT="aarch64-libreelec-linux-gnueabi-gcc-12.3.1 (GCC) 12.3.1 20240103" CONFIG_CC_IS_GCC=y @@ -351,53 +351,50 @@ CONFIG_ARCH_ROCKCHIP=y # # ARM errata workarounds via the alternatives framework # -CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y -CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_1742098=y -CONFIG_ARM64_ERRATUM_845719=y -CONFIG_ARM64_ERRATUM_843419=y +# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set +# CONFIG_ARM64_ERRATUM_826319 is not set +# CONFIG_ARM64_ERRATUM_827319 is not set +# CONFIG_ARM64_ERRATUM_824069 is not set +# CONFIG_ARM64_ERRATUM_819472 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_ARM64_ERRATUM_1742098 is not set +# CONFIG_ARM64_ERRATUM_845719 is not set +# CONFIG_ARM64_ERRATUM_843419 is not set CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y CONFIG_ARM64_ERRATUM_1024718=y -CONFIG_ARM64_ERRATUM_1418040=y +# CONFIG_ARM64_ERRATUM_1418040 is not set CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y -CONFIG_ARM64_ERRATUM_1165522=y -CONFIG_ARM64_ERRATUM_1319367=y +# CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_1319367 is not set CONFIG_ARM64_ERRATUM_1530923=y CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y CONFIG_ARM64_ERRATUM_2441007=y -CONFIG_ARM64_ERRATUM_1286807=y -CONFIG_ARM64_ERRATUM_1463225=y -CONFIG_ARM64_ERRATUM_1542419=y -CONFIG_ARM64_ERRATUM_1508412=y -CONFIG_ARM64_ERRATUM_2051678=y -CONFIG_ARM64_ERRATUM_2077057=y -CONFIG_ARM64_ERRATUM_2658417=y -CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y -CONFIG_ARM64_ERRATUM_2054223=y -CONFIG_ARM64_ERRATUM_2067961=y -CONFIG_ARM64_ERRATUM_2441009=y -CONFIG_ARM64_ERRATUM_2457168=y -CONFIG_ARM64_ERRATUM_2645198=y -CONFIG_ARM64_ERRATUM_2966298=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CAVIUM_ERRATUM_30115=y -CONFIG_CAVIUM_TX2_ERRATUM_219=y -CONFIG_FUJITSU_ERRATUM_010001=y -CONFIG_HISILICON_ERRATUM_161600802=y -CONFIG_QCOM_FALKOR_ERRATUM_1003=y -CONFIG_QCOM_FALKOR_ERRATUM_1009=y -CONFIG_QCOM_QDF2400_ERRATUM_0065=y -CONFIG_QCOM_FALKOR_ERRATUM_E1041=y -CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y -CONFIG_ROCKCHIP_ERRATUM_3588001=y -CONFIG_SOCIONEXT_SYNQUACER_PREITS=y +# CONFIG_ARM64_ERRATUM_1286807 is not set +# CONFIG_ARM64_ERRATUM_1463225 is not set +# CONFIG_ARM64_ERRATUM_1542419 is not set +# CONFIG_ARM64_ERRATUM_1508412 is not set +# CONFIG_ARM64_ERRATUM_2051678 is not set +# CONFIG_ARM64_ERRATUM_2077057 is not set +# CONFIG_ARM64_ERRATUM_2658417 is not set +# CONFIG_ARM64_ERRATUM_2054223 is not set +# CONFIG_ARM64_ERRATUM_2067961 is not set +# CONFIG_ARM64_ERRATUM_2441009 is not set +# CONFIG_ARM64_ERRATUM_2645198 is not set +# CONFIG_ARM64_ERRATUM_2966298 is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +# CONFIG_FUJITSU_ERRATUM_010001 is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set +# CONFIG_ROCKCHIP_ERRATUM_3588001 is not set +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set # end of ARM errata workarounds via the alternatives framework CONFIG_ARM64_4K_PAGES=y @@ -437,7 +434,7 @@ CONFIG_TRANS_TABLE=y # CONFIG_XEN is not set CONFIG_ARCH_FORCE_MAX_ORDER=10 CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y +# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set CONFIG_RODATA_FULL_DEFAULT_ENABLED=y # CONFIG_ARM64_SW_TTBR0_PAN is not set CONFIG_ARM64_TAGGED_ADDR_ABI=y @@ -462,15 +459,14 @@ CONFIG_ARM64_USE_LSE_ATOMICS=y CONFIG_AS_HAS_ARMV8_2=y CONFIG_AS_HAS_SHA3=y # CONFIG_ARM64_PMEM is not set -CONFIG_ARM64_RAS_EXTN=y -CONFIG_ARM64_CNP=y +# CONFIG_ARM64_RAS_EXTN is not set +# CONFIG_ARM64_CNP is not set # end of ARMv8.2 architectural features # # ARMv8.3 architectural features # -CONFIG_ARM64_PTR_AUTH=y -CONFIG_ARM64_PTR_AUTH_KERNEL=y +# CONFIG_ARM64_PTR_AUTH is not set CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y CONFIG_AS_HAS_ARMV8_3=y @@ -481,26 +477,26 @@ CONFIG_AS_HAS_LDAPR=y # # ARMv8.4 architectural features # -CONFIG_ARM64_AMU_EXTN=y +# CONFIG_ARM64_AMU_EXTN is not set CONFIG_AS_HAS_ARMV8_4=y -CONFIG_ARM64_TLB_RANGE=y +# CONFIG_ARM64_TLB_RANGE is not set # end of ARMv8.4 architectural features # # ARMv8.5 architectural features # CONFIG_AS_HAS_ARMV8_5=y -CONFIG_ARM64_BTI=y +# CONFIG_ARM64_BTI is not set CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y -CONFIG_ARM64_E0PD=y +# CONFIG_ARM64_E0PD is not set CONFIG_ARM64_AS_HAS_MTE=y -CONFIG_ARM64_MTE=y +# CONFIG_ARM64_MTE is not set # end of ARMv8.5 architectural features # # ARMv8.7 architectural features # -CONFIG_ARM64_EPAN=y +# CONFIG_ARM64_EPAN is not set # end of ARMv8.7 architectural features CONFIG_ARM64_SVE=y @@ -509,7 +505,6 @@ CONFIG_ARM64_SME=y CONFIG_RELOCATABLE=y # CONFIG_RANDOMIZE_BASE is not set CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_STACKPROTECTOR_PER_TASK=y # end of Kernel Features # @@ -611,7 +606,6 @@ CONFIG_HAVE_KVM=y # # General architecture-dependent options # -CONFIG_ARCH_HAS_SUBPAGE_FAULTS=y CONFIG_HOTPLUG_CORE_SYNC=y CONFIG_HOTPLUG_CORE_SYNC_DEAD=y # CONFIG_KPROBES is not set @@ -661,8 +655,7 @@ CONFIG_SECCOMP_FILTER=y # CONFIG_SECCOMP_CACHE_DEBUG is not set CONFIG_HAVE_ARCH_STACKLEAK=y CONFIG_HAVE_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR_STRONG=y +# CONFIG_STACKPROTECTOR is not set CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK=y # CONFIG_SHADOW_CALL_STACK is not set CONFIG_ARCH_SUPPORTS_LTO_CLANG=y @@ -949,8 +942,6 @@ CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_ARCH_HAS_ZONE_DMA_SET=y CONFIG_ZONE_DMA=y CONFIG_ZONE_DMA32=y -CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y -CONFIG_ARCH_USES_PG_ARCH_X=y CONFIG_VM_EVENT_COUNTERS=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_TEST is not set @@ -1350,10 +1341,8 @@ CONFIG_BT_HCIUART_BCM=y # CONFIG_AF_KCM is not set # CONFIG_MCTP is not set CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y CONFIG_CFG80211=m # CONFIG_NL80211_TESTMODE is not set # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set @@ -2061,7 +2050,6 @@ CONFIG_WLCORE=m CONFIG_WLAN_VENDOR_QUANTENNA=y CONFIG_ESP8089=m CONFIG_ESP8089_DEBUG_FS=y -# CONFIG_MAC80211_HWSIM is not set CONFIG_USB_NET_RNDIS_WLAN=m # CONFIG_MAC80211_HWSIM is not set # CONFIG_VIRT_WIFI is not set @@ -2175,6 +2163,7 @@ CONFIG_JOYSTICK_ADC=y CONFIG_JOYSTICK_ODROIDGO2=y CONFIG_JOYSTICK_ODROIDGO2_V11=y CONFIG_JOYSTICK_ODROIDGO3=y +CONFIG_JOYSTICK_RGB20S=y CONFIG_JOYSTICK_XU10=y # CONFIG_JOYSTICK_SENSEHAT is not set # CONFIG_INPUT_TABLET is not set @@ -2508,7 +2497,7 @@ CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_DEBUG_GPIO=y +# CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_CDEV_V1=y @@ -4417,8 +4406,6 @@ CONFIG_MMC_CQHCI=y # CONFIG_MMC_HSQ is not set # CONFIG_MMC_MTK is not set # CONFIG_MMC_SDHCI_XENON is not set -# CONFIG_MMC_SDHCI_OMAP is not set -# CONFIG_MMC_SDHCI_AM654 is not set # CONFIG_SCSI_UFSHCD is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -6477,7 +6464,6 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_HAVE_ARCH_KASAN=y CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y -CONFIG_HAVE_ARCH_KASAN_HW_TAGS=y CONFIG_HAVE_ARCH_KASAN_VMALLOC=y CONFIG_CC_HAS_KASAN_GENERIC=y CONFIG_CC_HAS_KASAN_SW_TAGS=y diff --git a/projects/Rockchip/devices/RK3326/options b/projects/Rockchip/devices/RK3326/options index 934bdac91f..b623db4d3c 100644 --- a/projects/Rockchip/devices/RK3326/options +++ b/projects/Rockchip/devices/RK3326/options @@ -31,7 +31,7 @@ BOOTLOADER="u-boot" TRUST_LABEL="trust" PARTITION_TABLE="msdos" - DEVICE_DTB=("rk3326-anbernic-rg351m" "rk3326-anbernic-rg351v" "rk3326-odroid-go2" "rk3326-odroid-go2-v11" "rk3326-odroid-go3" "rk3326-powkiddy-rgb10" "rk3326-magicx-xu10") + DEVICE_DTB=("rk3326-anbernic-rg351m" "rk3326-anbernic-rg351v" "rk3326-gameconsole-r33s" "rk3326-odroid-go2" "rk3326-odroid-go2-v11" "rk3326-odroid-go3" "rk3326-powkiddy-rgb10" "rk3326-powkiddy-rgb20s" "rk3326-magicx-xu10") UBOOT_DTB="${DEVICE_DTB[0]}" UBOOT_CONFIG="odroidgoa_defconfig" PKG_SOC="px30" @@ -124,6 +124,9 @@ # build and install OpenVPN support (yes / no) OPENVPN_SUPPORT="no" + # build and install ZeroTier support (yes / no) + ZEROTIER_SUPPORT="yes" + # build and install diskmounter support (udevil) # this service provide auto mounting support for external drives in the # mediacenter also automount internally drives at boottime via udev (yes / no) diff --git a/projects/Rockchip/devices/RK3399/linux/linux.aarch64.conf b/projects/Rockchip/devices/RK3399/linux/linux.aarch64.conf index d64d296e23..dc616d0eaf 100644 --- a/projects/Rockchip/devices/RK3399/linux/linux.aarch64.conf +++ b/projects/Rockchip/devices/RK3399/linux/linux.aarch64.conf @@ -1,10 +1,10 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 6.7.0 Kernel Configuration +# Linux/arm64 6.7.1 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="aarch64-libreelec-linux-gnueabi-gcc-12.3.0 (GCC) 12.3.0" +CONFIG_CC_VERSION_TEXT="aarch64-libreelec-linux-gnueabi-gcc-12.3.1 (GCC) 12.3.1 20240103" CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=120300 +CONFIG_GCC_VERSION=120301 CONFIG_CLANG_VERSION=0 CONFIG_AS_IS_GNU=y CONFIG_AS_VERSION=24100 @@ -430,7 +430,7 @@ CONFIG_TRANS_TABLE=y # CONFIG_XEN is not set CONFIG_ARCH_FORCE_MAX_ORDER=10 CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y +# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set CONFIG_RODATA_FULL_DEFAULT_ENABLED=y # CONFIG_ARM64_SW_TTBR0_PAN is not set CONFIG_ARM64_TAGGED_ADDR_ABI=y @@ -464,8 +464,9 @@ CONFIG_AS_HAS_SHA3=y # CONFIG_ARM64_PTR_AUTH is not set CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y -# CONFIG_AS_HAS_ARMV8_3 is not set +CONFIG_AS_HAS_ARMV8_3=y CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y +CONFIG_AS_HAS_LDAPR=y # end of ARMv8.3 architectural features # @@ -497,7 +498,6 @@ CONFIG_ARM64_SME=y CONFIG_RELOCATABLE=y # CONFIG_RANDOMIZE_BASE is not set CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_STACKPROTECTOR_PER_TASK=y # end of Kernel Features # @@ -598,6 +598,7 @@ CONFIG_HOTPLUG_CORE_SYNC=y CONFIG_HOTPLUG_CORE_SYNC_DEAD=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y @@ -642,8 +643,7 @@ CONFIG_SECCOMP_FILTER=y # CONFIG_SECCOMP_CACHE_DEBUG is not set CONFIG_HAVE_ARCH_STACKLEAK=y CONFIG_HAVE_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR_STRONG=y +# CONFIG_STACKPROTECTOR is not set CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK=y # CONFIG_SHADOW_CALL_STACK is not set CONFIG_ARCH_SUPPORTS_LTO_CLANG=y @@ -730,11 +730,13 @@ CONFIG_MODPROBE_PATH="/sbin/modprobe" CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y # CONFIG_BLOCK_LEGACY_AUTOLOAD is not set +CONFIG_BLK_CGROUP_RWSTAT=y CONFIG_BLK_DEV_BSG_COMMON=y CONFIG_BLK_DEV_BSGLIB=y # CONFIG_BLK_DEV_INTEGRITY is not set # CONFIG_BLK_DEV_ZONED is not set CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_DEV_THROTTLING_LOW is not set # CONFIG_BLK_WBT is not set # CONFIG_BLK_CGROUP_IOLATENCY is not set # CONFIG_BLK_CGROUP_IOCOST is not set @@ -805,31 +807,7 @@ CONFIG_ARCH_INLINE_WRITE_UNLOCK=y CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_SPIN_TRYLOCK=y -CONFIG_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_INLINE_SPIN_LOCK=y -CONFIG_INLINE_SPIN_LOCK_BH=y -CONFIG_INLINE_SPIN_LOCK_IRQ=y -CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_INLINE_SPIN_UNLOCK_BH=y -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_READ_LOCK=y -CONFIG_INLINE_READ_LOCK_BH=y -CONFIG_INLINE_READ_LOCK_IRQ=y -CONFIG_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_INLINE_READ_UNLOCK=y -CONFIG_INLINE_READ_UNLOCK_BH=y -CONFIG_INLINE_READ_UNLOCK_IRQ=y -CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_WRITE_LOCK=y -CONFIG_INLINE_WRITE_LOCK_BH=y -CONFIG_INLINE_WRITE_LOCK_IRQ=y -CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_INLINE_WRITE_UNLOCK=y -CONFIG_INLINE_WRITE_UNLOCK_BH=y -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y +CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_RWSEM_SPIN_ON_OWNER=y @@ -889,7 +867,6 @@ CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_FAST_GUP=y CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y # CONFIG_MEMORY_HOTPLUG is not set @@ -1379,6 +1356,7 @@ CONFIG_DEV_COREDUMP=y # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_SOC_BUS=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SPI=y @@ -1988,12 +1966,35 @@ CONFIG_INPUT_RK805_PWRKEY=y # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set -# CONFIG_RMI4_CORE is not set +CONFIG_RMI4_CORE=m +# CONFIG_RMI4_I2C is not set +# CONFIG_RMI4_SPI is not set +# CONFIG_RMI4_SMB is not set +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=m +CONFIG_RMI4_2D_SENSOR=y +CONFIG_RMI4_F11=y +CONFIG_RMI4_F12=y +CONFIG_RMI4_F30=y +# CONFIG_RMI4_F34 is not set +# CONFIG_RMI4_F3A is not set +# CONFIG_RMI4_F54 is not set +# CONFIG_RMI4_F55 is not set # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=m +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set # CONFIG_GAMEPORT is not set # end of Hardware I/O ports # end of Input device support @@ -2108,6 +2109,7 @@ CONFIG_I2C_DEMUX_PINCTRL=y # end of Multiplexer I2C Chip support CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m # # I2C Hardware Bus support @@ -2121,7 +2123,6 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_DESIGNWARE_CORE=y # CONFIG_I2C_DESIGNWARE_SLAVE is not set CONFIG_I2C_DESIGNWARE_PLATFORM=y -# CONFIG_I2C_DESIGNWARE_PCI is not set # CONFIG_I2C_EMEV2 is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_GPIO_FAULT_INJECTOR is not set @@ -2169,6 +2170,7 @@ CONFIG_SPI_MEM=y CONFIG_SPI_BITBANG=y # CONFIG_SPI_CADENCE is not set # CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_CADENCE_XSPI is not set # CONFIG_SPI_DESIGNWARE is not set CONFIG_SPI_GPIO=y # CONFIG_SPI_FSL_SPI is not set @@ -2180,6 +2182,7 @@ CONFIG_SPI_ROCKCHIP=y CONFIG_SPI_ROCKCHIP_SFC=y # CONFIG_SPI_SC18IS602 is not set # CONFIG_SPI_SIFIVE is not set +# CONFIG_SPI_SN_F_OSPI is not set # CONFIG_SPI_MXIC is not set # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set @@ -2335,7 +2338,7 @@ CONFIG_POWER_RESET=y CONFIG_POWER_RESET_GPIO=y CONFIG_POWER_RESET_GPIO_RESTART=y # CONFIG_POWER_RESET_LTC2952 is not set -CONFIG_POWER_RESET_REGULATOR=y +# CONFIG_POWER_RESET_REGULATOR is not set # CONFIG_POWER_RESET_RESTART is not set # CONFIG_POWER_RESET_XGENE is not set CONFIG_POWER_RESET_SYSCON=y @@ -2413,10 +2416,10 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_AHT10 is not set +# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set # CONFIG_SENSORS_AS370 is not set # CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_AXI_FAN_CONTROL is not set -# CONFIG_SENSORS_ARM_SCMI is not set # CONFIG_SENSORS_ARM_SCPI is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_CORSAIR_CPRO is not set @@ -2500,6 +2503,8 @@ CONFIG_HWMON=y # CONFIG_SENSORS_NCT7802 is not set # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_NPCM7XX is not set +# CONFIG_SENSORS_NZXT_KRAKEN2 is not set +# CONFIG_SENSORS_NZXT_SMART2 is not set # CONFIG_SENSORS_OCC_P8_I2C is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set @@ -2557,15 +2562,13 @@ CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y CONFIG_THERMAL_WRITABLE_TRIPS=y -# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y # CONFIG_THERMAL_GOV_BANG_BANG is not set # CONFIG_THERMAL_GOV_USER_SPACE is not set -CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y CONFIG_CPU_FREQ_THERMAL=y CONFIG_DEVFREQ_THERMAL=y @@ -2749,7 +2752,6 @@ CONFIG_REGULATOR_USERSPACE_CONSUMER=y # CONFIG_REGULATOR_88PG86X is not set # CONFIG_REGULATOR_ACT8865 is not set # CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ARM_SCMI is not set # CONFIG_REGULATOR_AW37503 is not set # CONFIG_REGULATOR_DA9121 is not set # CONFIG_REGULATOR_DA9210 is not set @@ -3423,6 +3425,7 @@ CONFIG_SND_PCM_ELD=y CONFIG_SND_PCM_IEC958=y CONFIG_SND_DMAENGINE_PCM=y CONFIG_SND_SEQ_DEVICE=y +CONFIG_SND_RAWMIDI=m CONFIG_SND_JACK=y CONFIG_SND_JACK_INPUT_DEV=y # CONFIG_SND_OSSEMUL is not set @@ -3438,6 +3441,8 @@ CONFIG_SND_CTL_FAST_LOOKUP=y # CONFIG_SND_CTL_INPUT_VALIDATION is not set CONFIG_SND_SEQUENCER=y # CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_SEQ_MIDI_EVENT=m +CONFIG_SND_SEQ_MIDI=m # CONFIG_SND_SEQ_UMP is not set # CONFIG_SND_DRIVERS is not set @@ -3711,77 +3716,128 @@ CONFIG_HID_GENERIC=y # # Special HID drivers # -# CONFIG_HID_A4TECH is not set -# CONFIG_HID_ACRUX is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_AUREAL is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_CHERRY is not set +CONFIG_HID_A4TECH=m +# CONFIG_HID_ACCUTOUCH is not set +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=m +CONFIG_HID_APPLEIR=m +# CONFIG_HID_ASUS is not set +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +# CONFIG_HID_BIGBEN_FF is not set +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CORSAIR=m # CONFIG_HID_COUGAR is not set # CONFIG_HID_MACALLY is not set +CONFIG_HID_PRODIKEYS=m # CONFIG_HID_CMEDIA is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_DRAGONRISE is not set -# CONFIG_HID_EMS_FF is not set -# CONFIG_HID_ELECOM is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +# CONFIG_HID_ELAN is not set +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m # CONFIG_HID_EVISION is not set -# CONFIG_HID_EZKEY is not set -# CONFIG_HID_GEMBIRD is not set -# CONFIG_HID_GFRM is not set +CONFIG_HID_EZKEY=m +# CONFIG_HID_FT260 is not set +CONFIG_HID_GEMBIRD=m +CONFIG_HID_GFRM=m # CONFIG_HID_GLORIOUS is not set +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y # CONFIG_HID_GOOGLE_STADIA_FF is not set # CONFIG_HID_VIVALDI is not set -# CONFIG_HID_KEYTOUCH is not set -# CONFIG_HID_KYE is not set -# CONFIG_HID_WALTOP is not set +CONFIG_HID_GT683R=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m # CONFIG_HID_VIEWSONIC is not set # CONFIG_HID_VRC2 is not set # CONFIG_HID_XIAOMI is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_ICADE is not set +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m # CONFIG_HID_ITE is not set # CONFIG_HID_JABRA is not set -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_KENSINGTON is not set -# CONFIG_HID_LCPOWER is not set -# CONFIG_HID_LED is not set -# CONFIG_HID_LENOVO is not set -# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LED=m +CONFIG_HID_LENOVO=m +# CONFIG_HID_LETSKETCH is not set +CONFIG_HID_LOGITECH=m +# CONFIG_HID_LOGITECH_DJ is not set +CONFIG_HID_LOGITECH_HIDPP=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_MAGICMOUSE=m # CONFIG_HID_MALTRON is not set # CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set # CONFIG_HID_REDRAGON is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_HID_MULTITOUCH is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m # CONFIG_HID_NINTENDO is not set # CONFIG_HID_NTI is not set -# CONFIG_HID_ORTEK is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_PICOLCD is not set -# CONFIG_HID_PLANTRONICS is not set +CONFIG_HID_NTRIG=m +# CONFIG_HID_NVIDIA_SHIELD is not set +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PENMOUNT=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PICOLCD_BACKLIGHT=y +CONFIG_HID_PICOLCD_LEDS=y +CONFIG_HID_PLANTRONICS=m # CONFIG_HID_PXRC is not set # CONFIG_HID_RAZER is not set -# CONFIG_HID_PRIMAX is not set -# CONFIG_HID_SAITEK is not set +CONFIG_HID_PRIMAX=m +# CONFIG_HID_RETRODE is not set +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m # CONFIG_HID_SEMITEK is not set -# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_SIGMAMICRO is not set +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m # CONFIG_HID_STEAM is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_HID_RMI is not set -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_SMARTJOYPLUS is not set -# CONFIG_HID_TIVO is not set -# CONFIG_HID_TOPSEED is not set +CONFIG_HID_STEELSERIES=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_RMI=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=m +CONFIG_HID_TOPSEED=m # CONFIG_HID_TOPRE is not set -# CONFIG_HID_THINGM is not set +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y # CONFIG_HID_UDRAW_PS3 is not set -# CONFIG_HID_WIIMOTE is not set -# CONFIG_HID_XINMO is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -# CONFIG_HID_SENSOR_HUB is not set -# CONFIG_HID_ALPS is not set +# CONFIG_HID_U2FZERO is not set +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=m +CONFIG_HID_SENSOR_HUB=m +CONFIG_HID_SENSOR_CUSTOM_SENSOR=m +CONFIG_HID_ALPS=m +# CONFIG_HID_MCP2221 is not set # end of Special HID drivers # @@ -3792,15 +3848,9 @@ CONFIG_HID_GENERIC=y # # USB HID support # -# CONFIG_USB_HID is not set +CONFIG_USB_HID=y # CONFIG_HID_PID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# end of USB HID Boot Protocol drivers +CONFIG_USB_HIDDEV=y # end of USB HID support CONFIG_I2C_HID=y @@ -4078,12 +4128,10 @@ CONFIG_MMC_DW_ROCKCHIP=y # CONFIG_MMC_VUB300 is not set # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set -# CONFIG_MMC_CQHCI is not set +CONFIG_MMC_CQHCI=y # CONFIG_MMC_HSQ is not set # CONFIG_MMC_MTK is not set # CONFIG_MMC_SDHCI_XENON is not set -# CONFIG_MMC_SDHCI_OMAP is not set -# CONFIG_MMC_SDHCI_AM654 is not set # CONFIG_SCSI_UFSHCD is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -4285,6 +4333,7 @@ CONFIG_RTC_I2C_AND_SPI=y # # HID Sensor RTC drivers # +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set # CONFIG_RTC_DRV_GOLDFISH is not set CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -4421,7 +4470,6 @@ CONFIG_COMMON_CLK=y # CONFIG_LMK04832 is not set # CONFIG_COMMON_CLK_MAX9485 is not set CONFIG_COMMON_CLK_RK808=y -CONFIG_COMMON_CLK_SCMI=y CONFIG_COMMON_CLK_SCPI=y # CONFIG_COMMON_CLK_SI5341 is not set # CONFIG_COMMON_CLK_SI5351 is not set @@ -4673,6 +4721,7 @@ CONFIG_IIO_TRIGGERED_EVENT=y # CONFIG_DMARD10 is not set # CONFIG_FXLS8962AF_I2C is not set # CONFIG_FXLS8962AF_SPI is not set +# CONFIG_HID_SENSOR_ACCEL_3D is not set # CONFIG_IIO_ST_ACCEL_3AXIS is not set # CONFIG_IIO_KX022A_SPI is not set # CONFIG_IIO_KX022A_I2C is not set @@ -4817,12 +4866,12 @@ CONFIG_ROCKCHIP_SARADC=y # # Hid Sensor IIO Common # +# CONFIG_HID_SENSOR_IIO_COMMON is not set # end of Hid Sensor IIO Common # # IIO SCMI Sensors # -# CONFIG_IIO_SCMI is not set # end of IIO SCMI Sensors # @@ -4922,6 +4971,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_ADXRS450 is not set # CONFIG_BMG160 is not set # CONFIG_FXAS21002C is not set +# CONFIG_HID_SENSOR_GYRO_3D is not set # CONFIG_MPU3050_I2C is not set # CONFIG_IIO_ST_GYRO_3AXIS is not set # CONFIG_ITG3200 is not set @@ -4948,6 +4998,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set # CONFIG_HDC2010 is not set +# CONFIG_HID_SENSOR_HUMIDITY is not set # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set # CONFIG_SI7005 is not set @@ -4998,6 +5049,8 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_SENSORS_ISL29018 is not set # CONFIG_SENSORS_ISL29028 is not set # CONFIG_ISL29125 is not set +# CONFIG_HID_SENSOR_ALS is not set +# CONFIG_HID_SENSOR_PROX is not set # CONFIG_JSA1212 is not set # CONFIG_ROHM_BU27008 is not set # CONFIG_ROHM_BU27034 is not set @@ -5040,6 +5093,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_BMC150_MAGN_I2C is not set # CONFIG_BMC150_MAGN_SPI is not set # CONFIG_MAG3110 is not set +# CONFIG_HID_SENSOR_MAGNETOMETER_3D is not set # CONFIG_MMC35240 is not set # CONFIG_IIO_ST_MAGN_3AXIS is not set # CONFIG_SENSORS_HMC5843_I2C is not set @@ -5059,6 +5113,8 @@ CONFIG_IIO_MUX=y # # Inclinometer sensors # +# CONFIG_HID_SENSOR_INCLINOMETER_3D is not set +# CONFIG_HID_SENSOR_DEVICE_ROTATION is not set # end of Inclinometer sensors # @@ -5073,6 +5129,7 @@ CONFIG_IIO_SYSFS_TRIGGER=y # # Linear and angular position sensors # +# CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE is not set # end of Linear and angular position sensors # @@ -5106,6 +5163,7 @@ CONFIG_IIO_SYSFS_TRIGGER=y # CONFIG_BMP280 is not set # CONFIG_DLHL60D is not set # CONFIG_DPS310 is not set +# CONFIG_HID_SENSOR_PRESS is not set # CONFIG_HP03 is not set # CONFIG_ICP10100 is not set # CONFIG_MPL115_I2C is not set @@ -5158,6 +5216,7 @@ CONFIG_IIO_SYSFS_TRIGGER=y # # CONFIG_LTC2983 is not set # CONFIG_MAXIM_THERMOCOUPLE is not set +# CONFIG_HID_SENSOR_TEMP is not set # CONFIG_MLX90614 is not set # CONFIG_MLX90632 is not set # CONFIG_TMP006 is not set @@ -5196,7 +5255,6 @@ CONFIG_PARTITION_PERCPU=y # CONFIG_IPACK_BUS is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y CONFIG_RESET_CONTROLLER=y -CONFIG_RESET_SCMI=y # CONFIG_RESET_SIMPLE is not set # CONFIG_RESET_TI_SYSCON is not set # CONFIG_RESET_TI_TPS380X is not set @@ -5939,6 +5997,8 @@ CONFIG_SGL_ALLOC=y # CONFIG_FORCE_NR_CPUS is not set CONFIG_CPU_RMAP=y CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_CLZ_TAB=y CONFIG_IRQ_POLL=y @@ -6040,7 +6100,6 @@ CONFIG_HAVE_KCSAN_COMPILER=y # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_SLUB_DEBUG is not set # CONFIG_PAGE_OWNER is not set -# CONFIG_PAGE_TABLE_CHECK is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_RODATA_TEST is not set CONFIG_ARCH_HAS_DEBUG_WX=y @@ -6095,8 +6154,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y # Scheduler Debugging # # CONFIG_SCHED_DEBUG is not set -CONFIG_SCHED_INFO=y -CONFIG_SCHEDSTATS=y +# CONFIG_SCHEDSTATS is not set # end of Scheduler Debugging # CONFIG_DEBUG_TIMEKEEPING is not set diff --git a/projects/Rockchip/devices/RK3566-X55/options b/projects/Rockchip/devices/RK3566-X55/options index 5249c3b351..84fba2cb9c 100644 --- a/projects/Rockchip/devices/RK3566-X55/options +++ b/projects/Rockchip/devices/RK3566-X55/options @@ -31,7 +31,7 @@ BOOTLOADER="u-boot" PARTITION_TABLE="gpt" UBOOT_LABEL="uboot" - TRUST_LABEL="resource" + TRUST_LABEL="trust" DEVICE_DTB=("rk3566-evb2-lp4x-v10-linux") UBOOT_DTB="rk3566" UBOOT_CONFIG="rk3568_defconfig" diff --git a/projects/Rockchip/devices/RK3566/options b/projects/Rockchip/devices/RK3566/options index c53c843961..baf3ff453e 100644 --- a/projects/Rockchip/devices/RK3566/options +++ b/projects/Rockchip/devices/RK3566/options @@ -32,7 +32,7 @@ PARTITION_TABLE="gpt" UBOOT_LABEL="uboot" TRUST_LABEL="resource" - DEVICE_DTB=("rk3566-rg353p-linux" "rk3566-rg353v-linux" "rk3566-rg353m-linux" "rk3566-rg503-linux" "rk3566-rk2023-linux" "rk3566-rgb30-linux") + DEVICE_DTB=("rk3566-rg353p-linux" "rk3566-rg353v-linux" "rk3566-rg353m-linux" "rk3566-rg503-linux" "rk3566-rk2023-linux" "rk3566-rgb30-linux" "rk3566-max3pro-linux") UBOOT_DTB="rk3566" UBOOT_CONFIG="rk3568_defconfig" PKG_SOC="rk356x" @@ -72,7 +72,7 @@ # additional Firmware to use (dvb-firmware, misc-firmware, wlan-firmware) # Space separated list is supported, # e.g. FIRMWARE="dvb-firmware misc-firmware wlan-firmware" - FIRMWARE="misc-firmware wlan-firmware RTL8821CS-firmware" + FIRMWARE="misc-firmware wlan-firmware RTL8821CS-firmware RTL8723DS-firmware" # additional drivers to install: # for a list of additional drivers see packages/linux-drivers diff --git a/projects/Rockchip/packages/linux/package.mk b/projects/Rockchip/packages/linux/package.mk index ce02854358..d0a8bd1e01 100644 --- a/projects/Rockchip/packages/linux/package.mk +++ b/projects/Rockchip/packages/linux/package.mk @@ -25,7 +25,7 @@ case ${DEVICE} in ;; RK3566) PKG_URL="${PKG_SITE}/rk356x-kernel.git" - PKG_VERSION="d346337a7b3e3e7e0d12dbdcc4fc62efc86cbda3" + PKG_VERSION="c741d56477939654bb4056be240f93d1ad1ae91e" GET_HANDLER_SUPPORT="git" PKG_GIT_CLONE_BRANCH="main" ;; @@ -36,7 +36,7 @@ case ${DEVICE} in PKG_GIT_CLONE_BRANCH="main" ;; RK3399|RK3326) - PKG_VERSION="6.7" + PKG_VERSION="6.7.2" PKG_URL="https://www.kernel.org/pub/linux/kernel/v6.x/${PKG_NAME}-${PKG_VERSION}.tar.xz" ;; esac diff --git a/projects/Rockchip/packages/linux/patches/RK3326/000-rk3326-dts.patch b/projects/Rockchip/packages/linux/patches/RK3326/000-rk3326-dts.patch index 679f44ca10..9aab8b388b 100644 --- a/projects/Rockchip/packages/linux/patches/RK3326/000-rk3326-dts.patch +++ b/projects/Rockchip/packages/linux/patches/RK3326/000-rk3326-dts.patch @@ -1,23 +1,25 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/Makefile linux/arch/arm64/boot/dts/rockchip/Makefile ---- linux.orig/arch/arm64/boot/dts/rockchip/Makefile 2024-01-17 03:47:10.074350115 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/Makefile 2024-01-17 04:01:50.682844812 +0000 -@@ -9,9 +9,12 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-ro +--- linux.orig/arch/arm64/boot/dts/rockchip/Makefile 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/Makefile 2024-01-29 06:17:10.562382315 +0000 +@@ -9,9 +9,14 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-ro dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351m.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351v.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-gameconsole-r33s.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-magicx-xu10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2-v11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go3.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-powkiddy-rgb10.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-powkiddy-rgb20s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/px30.dtsi linux/arch/arm64/boot/dts/rockchip/px30.dtsi ---- linux.orig/arch/arm64/boot/dts/rockchip/px30.dtsi 2024-01-17 03:47:10.078350209 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/px30.dtsi 2024-01-17 03:59:58.108276677 +0000 -@@ -114,27 +114,11 @@ +--- linux.orig/arch/arm64/boot/dts/rockchip/px30.dtsi 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/px30.dtsi 2024-01-29 05:08:22.844542450 +0000 +@@ -114,32 +114,22 @@ compatible = "operating-points-v2"; opp-shared; @@ -45,7 +47,18 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/px30.dtsi linux/arch/arm64/bo opp-1296000000 { opp-hz = /bits/ 64 <1296000000>; opp-microvolt = <1350000 1350000 1350000>; -@@ -349,6 +333,32 @@ + clock-latency-ns = <40000>; + }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ clock-latency-ns = <40000>; ++ turbo-mode; ++ }; + }; + + arm-pmu { +@@ -349,6 +339,32 @@ }; }; @@ -78,7 +91,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/px30.dtsi linux/arch/arm64/bo pmugrf: syscon@ff010000 { compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd"; reg = <0x0 0xff010000 0x0 0x1000>; -@@ -1064,20 +1074,12 @@ +@@ -1064,21 +1080,9 @@ gpu_opp_table: opp-table-1 { compatible = "operating-points-v2"; @@ -90,20 +103,22 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/px30.dtsi linux/arch/arm64/bo - opp-hz = /bits/ 64 <300000000>; - opp-microvolt = <975000>; - }; - opp-400000000 { - opp-hz = /bits/ 64 <400000000>; - opp-microvolt = <1050000>; - }; +- opp-400000000 { +- opp-hz = /bits/ 64 <400000000>; +- opp-microvolt = <1050000>; +- }; - opp-480000000 { - opp-hz = /bits/ 64 <480000000>; -+ opp-440000000 { -+ opp-hz = /bits/ 64 <440000000>; - opp-microvolt = <1125000>; +- opp-microvolt = <1125000>; ++ opp-560000000 { ++ opp-hz = /bits/ 64 <560000000>; ++ opp-microvolt = <1150000>; }; }; + diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts linux/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts 2024-01-17 03:47:10.078350209 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts 2024-01-17 03:59:58.108276677 +0000 +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts 2024-01-29 05:08:22.844542450 +0000 @@ -12,6 +12,25 @@ model = "Anbernic RG351M"; compatible = "anbernic,rg351m", "rockchip,rk3326"; @@ -156,7 +171,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351m.dts li +}; diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts linux/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts --- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts 1970-01-01 00:00:00.000000000 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts 2024-01-17 03:59:58.108276677 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts 2024-01-29 05:08:22.844542450 +0000 @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* @@ -282,9 +297,10 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + }; + }; +}; ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-magicx-xu10.dts 1969-12-31 19:00:00.000000000 -0500 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-magicx-xu10.dts 2024-01-19 15:39:57.362135961 -0500 -@@ -0,0 +1,848 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-gameconsole-r33s.dts linux/arch/arm64/boot/dts/rockchip/rk3326-gameconsole-r33s.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-gameconsole-r33s.dts 1970-01-01 00:00:00.000000000 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-gameconsole-r33s.dts 2024-01-29 05:08:22.844542450 +0000 +@@ -0,0 +1,646 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd @@ -300,182 +316,820 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li +#include "rk3326.dtsi" + +/ { -+ model = "MagicX XU10"; -+ compatible = "magicx,xu10", "rockchip,rk3326"; -+ -+ chosen { -+ bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootwait"; -+ }; ++ model = "Game Console R33S"; ++ compatible = "gameconsolec,r33s", "rockchip,rk3326"; + -+ fiq-debugger { -+ compatible = "rockchip,fiq-debugger"; -+ rockchip,serial-id = <2>; -+ rockchip,wake-irq = <0>; -+ /* If enable uart uses irq instead of fiq */ -+ rockchip,irq-mode-enable = <0>; -+ rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */ -+ interrupts = ; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2m1_xfer>; -+ status = "okay"; -+ }; ++ aliases { ++ mmc0 = &sdio; ++ mmc1 = &sdmmc; ++ }; + -+ backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm1 0 62745 0>; -+ brightness-levels = < -+ 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>; -+ default-brightness-level = <128>; -+ }; ++ chosen { ++ stdout-path = "serial2:115200n8"; ++ }; + -+ joypad: xu10-joypad { -+ compatible = "xu10-joypad"; ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ power-supply = <&vcc_bl>; ++ pwms = <&pwm1 0 25000 0>; ++ brightness-levels = < ++ 0 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>; ++ default-brightness-level = <128>; ++ }; + -+ joypad-name = "XU10 Gamepad"; -+ joypad-product = <0x0200>; -+ joypad-revision = <0x0010>; ++ gpio-keys-vol { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-0 = <&btn_pins_vol>; ++ pinctrl-names = "default"; + -+ status = "okay"; -+ /* -+ - xu10-joypad sysfs list - -+ * for poll device interval(ms) -+ /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] -+ ex) echo 20 > poll_interval -+ * for button-adc-fuzz -+ /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] -+ * for button-adc-flat -+ /sys/devices/platform/odroidgo3_joypad/adc_flat [r] ++ button-vol-down { ++ gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; ++ label = "VOLUMEDOWN"; ++ linux,code = ; ++ }; + -+ * for report control(1:enable, 0:disable) -+ /sys/devices/platform/odroidgo3_joypad/enable [rw] -+ * for adc calibration value setup(current adcs value -> cal value) -+ /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] -+ ex) echo 0 > adc_cal -+ * for amux data debug -+ * Joypad driver is disabled when using this sysfs. -+ /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] -+ ex) echo 0 > amux_debug --> select amux channel -+ ex) cat amux_debug --> get adc data of seleted channel -+ */ ++ button-volume-up { ++ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "VOLUMEUP"; ++ linux,code = ; ++ }; ++ }; + -+ /* gpio pincontrol setup */ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&btn_pins>; ++ builtin_gamepad: r33s_joypad { ++ compatible = "gpio-keys"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&btn_pins>; + -+ /* Analog mux define */ -+ io-channel-names = "joy_left", "joy_right"; -+ io-channels = <&saradc 1>, <&saradc 2>; ++ button-sw1 { ++ gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; ++ label = "DPAD-UP"; ++ linux,code = ; ++ }; ++ button-sw2 { ++ gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; ++ label = "DPAD-DOWN"; ++ linux,code = ; ++ }; ++ button-sw3 { ++ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; ++ label = "DPAD-LEFT"; ++ linux,code = ; ++ }; ++ button-sw4 { ++ gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; ++ label = "DPAD-RIGHT"; ++ linux,code = ; ++ }; ++ button-sw5 { ++ gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; ++ label = "BTN-A"; ++ linux,code = ; ++ }; ++ button-sw6 { ++ gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "BTN-B"; ++ linux,code = ; ++ }; ++ button-sw7 { ++ gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; ++ label = "BTN-Y"; ++ linux,code = ; ++ }; ++ button-sw8 { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "BTN-X"; ++ linux,code = ; ++ }; ++ button-sw9 { ++ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; ++ label = "TOP-LEFT"; ++ linux,code = ; ++ }; ++ button-sw10 { ++ gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "TOP-RIGHT"; ++ linux,code = ; ++ }; ++ button-sw11 { ++ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; ++ label = "SELECT"; ++ linux,code = ; ++ }; ++ button-sw12 { ++ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ label = "TOP-RIGHT 2"; ++ linux,code = ; ++ }; ++ button-sw13 { ++ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; ++ label = "TOP-LEFT 2"; ++ linux,code = ; ++ }; ++ button-sw14 { ++ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; ++ label = "START"; ++ linux,code = ; ++ }; ++ }; + -+ /* adc mux channel count */ -+ amux-count = <4>; ++ battery: battery { ++ compatible = "simple-battery"; ++ charge-full-design-microamp-hours = <3200000>; ++ charge-term-current-microamp = <320000>; ++ constant-charge-current-max-microamp = <2000000>; ++ constant-charge-voltage-max-microvolt = <4200000>; ++ factory-internal-resistance-micro-ohms = <180000>; ++ voltage-max-design-microvolt = <4100000>; ++ voltage-min-design-microvolt = <3500000>; + -+ /* adc mux select(a,b) gpio */ -+ amux-a-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>; -+ amux-b-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; ++ ocv-capacity-celsius = <20>; ++ ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, ++ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, ++ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, ++ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, ++ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, ++ <3574170 0>; ++ ++ }; + -+ /* adc mux enable gpio */ -+ amux-en-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>; ++ vibrator { ++ compatible = "pwm-vibrator"; ++ pwms = <&pwm0 0 1000000 0>; ++ pwm-names = "enable"; ++ }; + -+ /* adc calculate scale */ -+ button-adc-scale = <2>; ++ rk817-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "rk817_int"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Microphone", "Mic Jack", ++ "Headphone", "Headphones", ++ "Speaker", "Speaker"; ++ simple-audio-card,routing = ++ "MICL", "Mic Jack", ++ "Headphones", "HPOL", ++ "Headphones", "HPOR", ++ "Speaker", "SPKO"; ++ ++ simple-audio-card,codec { ++ sound-dai = <&rk817>; ++ }; + -+ /* adc deadzone range */ -+ button-adc-deadzone = <180>; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1_2ch>; ++ }; ++ }; + -+ /* -+ specifies fuzz value that is used to filter noise from -+ the event stream. -+ */ -+ button-adc-fuzz = <32>; -+ button-adc-flat = <32>; ++ vccsys: vccsys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v8_sys"; ++ regulator-always-on; ++ regulator-min-microvolt = <3800000>; ++ regulator-max-microvolt = <3800000>; ++ }; ++}; + -+ /* -+ Analog Stick data tuning value(precent) -+ p = positive direction, n = negative direction -+ report value = (real_adc_data * tuning_value) / 100 -+ */ -+ abs_x-p-tuning = <200>; -+ abs_x-n-tuning = <200>; ++&dmc { ++ center-supply = <&vdd_logic>; ++}; + -+ abs_y-p-tuning = <200>; -+ abs_y-n-tuning = <200>; ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; + -+ abs_rx-p-tuning = <200>; -+ abs_rx-n-tuning = <200>; ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; + -+ abs_ry-p-tuning = <200>; -+ abs_ry-n-tuning = <200>; ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; + -+ /* poll device interval (ms), adc read interval */ -+ poll-interval = <10>; -+ btn-lr-to-absx; -+ btn-ud-to-absy; -+ -+ /* gpio button auto repeat set value : default disable */ -+ /* -+ autorepeat; -+ */ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; + -+ /* -+ *** MagicX XU10 - layoout *** -+ |-------------------------------| -+ | sw14 sw17 sw16 sw15 | -+ |-----|-------------------|-----| -+ | | | | -+ |vol+ | | sw13| -+ |vol- | | | -+ | | LCD Display | | -+ | | | | -+ | | | | -+ | |-------------------| | -+ | sw9 sw10 | -+ | | -+ | sw1 sw7 | -+ | sw3 sw4 sw8 sw6 | -+ | sw2 sw5 | -+ | | -+ | sw11 sw12 | -+ | | -+ |-------|---------------|-------| -+ */ ++&cru { ++ assigned-clocks = <&cru PLL_NPLL>, ++ <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, ++ <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, ++ <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; ++ ++ assigned-clock-rates = <1188000000>, ++ <200000000>, <200000000>, ++ <150000000>, <150000000>, ++ <100000000>, <200000000>; ++}; + -+ /* -+ joypad driver is poll-device driver. -+ poll-device is does not support wakeup-source. -+ */ ++&display_subsystem { ++ status = "okay"; ++}; + -+ sw1 { ++&dsi { ++ status = "okay"; ++ ++ ports { ++ mipi_out: port@1 { ++ reg = <1>; ++ ++ mipi_out_panel: endpoint { ++ remote-endpoint = <&mipi_in_panel>; ++ }; ++ }; ++ }; ++ ++ internal_display: panel@0 { ++ reg = <0>; ++ backlight = <&backlight>; ++ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; ++ ++ port { ++ mipi_in_panel: endpoint { ++ remote-endpoint = <&mipi_out_panel>; ++ }; ++ }; ++ }; ++}; ++ ++&dsi_dphy { ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&internal_display { ++ compatible = "gameconsole,r36s-panel", "sitronix,st7703"; ++ iovcc-supply = <&vcc_lcd>; ++ vdd-supply = <&vcc_lcd>; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ i2c-scl-falling-time-ns = <16>; ++ i2c-scl-rising-time-ns = <280>; ++ status = "okay"; ++ ++ rk817: pmic@20 { ++ compatible = "rockchip,rk817"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ clock-output-names = "rk808-clkout1", "xin32k"; ++ clock-names = "mclk"; ++ clocks = <&cru SCLK_I2S1_OUT>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <1>; ++ #sound-dai-cells = <0>; ++ ++ vcc1-supply = <&vccsys>; ++ vcc2-supply = <&vccsys>; ++ vcc3-supply = <&vccsys>; ++ vcc4-supply = <&vccsys>; ++ vcc5-supply = <&vccsys>; ++ vcc6-supply = <&vccsys>; ++ vcc7-supply = <&vccsys>; ++ vcc8-supply = <&vccsys>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: DCDC_REG4 { ++ regulator-name = "vcc_3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_1v8: LDO_REG2 { ++ regulator-name = "vcc_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_1v0: LDO_REG3 { ++ regulator-name = "vdd_1v0"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG4 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sd: LDO_REG6 { ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc_bl: LDO_REG7 { ++ regulator-name = "vcc_bl"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_lcd: LDO_REG8 { ++ regulator-name = "vcc_lcd"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <2800000>; ++ }; ++ }; ++ ++ LDO_REG9 { ++ /* unused */ ++ }; ++ ++ usb_midu: BOOST { ++ regulator-name = "usb_midu"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5400000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ }; ++ ++ rk817_charger: charger { ++ rockchip,resistor-sense-micro-ohms = <10000>; ++ rockchip,sleep-enter-current-microamp = <300000>; ++ rockchip,sleep-filter-current-microamp = <100000>; ++ }; ++ ++ rk817_codec: codec { ++ rockchip,mic-in-differential; ++ }; ++ }; ++}; ++ ++&i2s1_2ch { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vccio_sd>; ++ vccio2-supply = <&vccio_sd>; ++ vccio3-supply = <&vcc_3v3>; ++ vccio4-supply = <&vcc_3v3>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ status = "okay"; ++}; ++ ++&pwm0 { ++ status = "okay"; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ card-detect-delay = <800>; ++ cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ ++ disable-wp; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ card-detect-delay = <800>; ++ cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ ++ disable-wp; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++ ++ u2phy_host: host-port { ++ status = "okay"; ++ }; ++ ++ u2phy_otg: otg-port { ++ status = "disabled"; ++ }; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2m1_xfer>; ++ status = "okay"; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&rk817_charger { ++ monitored-battery = <&battery>; ++}; ++ ++&pinctrl { ++ btns { ++ btn_pins: btn-pins { ++ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ btn_pins_vol: btn-pins-vol { ++ rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ headphone { ++ hp_det: hp-det { ++ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ pmic { ++ dc_det: dc-det { ++ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pmic_int: pmic-int { ++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ soc_slppin_gpio: soc_slppin_gpio { ++ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ ++ soc_slppin_rst: soc_slppin_rst { ++ rockchip,pins = <0 RK_PA4 2 &pcfg_pull_none>; ++ }; ++ ++ soc_slppin_slp: soc_slppin_slp { ++ rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>; ++ }; ++ }; ++}; +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-magicx-xu10.dts linux/arch/arm64/boot/dts/rockchip/rk3326-magicx-xu10.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-magicx-xu10.dts 1969-12-31 19:00:00.000000000 -0500 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-magicx-xu10.dts 2024-01-29 18:25:00.758766065 -0500 +@@ -0,0 +1,825 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2019 Hardkernel Co., Ltd ++ * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH ++ * Copyright (c) 2022 Maya Matuszczyk ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include ++#include ++#include "rk3326.dtsi" ++ ++/ { ++ model = "MagicX XU10"; ++ compatible = "magicx,xu10", "rockchip,rk3326"; ++ ++ aliases { ++ mmc0 = &sdio; ++ mmc1 = &sdmmc; ++ }; ++ ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm1 0 62745 0>; ++ brightness-levels = < ++ 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>; ++ default-brightness-level = <128>; ++ }; ++ ++ joypad: xu10-joypad { ++ compatible = "xu10-joypad"; ++ ++ joypad-name = "XU10 Gamepad"; ++ joypad-product = <0x0200>; ++ joypad-revision = <0x0010>; ++ ++ status = "okay"; ++ /* ++ - xu10-joypad sysfs list - ++ * for poll device interval(ms) ++ /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] ++ ex) echo 20 > poll_interval ++ * for button-adc-fuzz ++ /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] ++ * for button-adc-flat ++ /sys/devices/platform/odroidgo3_joypad/adc_flat [r] ++ ++ * for report control(1:enable, 0:disable) ++ /sys/devices/platform/odroidgo3_joypad/enable [rw] ++ * for adc calibration value setup(current adcs value -> cal value) ++ /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] ++ ex) echo 0 > adc_cal ++ * for amux data debug ++ * Joypad driver is disabled when using this sysfs. ++ /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] ++ ex) echo 0 > amux_debug --> select amux channel ++ ex) cat amux_debug --> get adc data of seleted channel ++ */ ++ ++ /* gpio pincontrol setup */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&btn_pins>; ++ ++ /* Analog mux define */ ++ io-channel-names = "joy_left", "joy_right"; ++ io-channels = <&saradc 1>, <&saradc 2>; ++ ++ /* adc mux channel count */ ++ amux-count = <4>; ++ ++ /* adc mux select(a,b) gpio */ ++ amux-a-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>; ++ amux-b-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; ++ ++ /* adc mux enable gpio */ ++ amux-en-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>; ++ ++ /* adc calculate scale */ ++ button-adc-scale = <2>; ++ ++ /* adc deadzone range */ ++ button-adc-deadzone = <180>; ++ ++ /* ++ specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ button-adc-fuzz = <32>; ++ button-adc-flat = <32>; ++ ++ /* ++ Analog Stick data tuning value(precent) ++ p = positive direction, n = negative direction ++ report value = (real_adc_data * tuning_value) / 100 ++ */ ++ abs_x-p-tuning = <200>; ++ abs_x-n-tuning = <200>; ++ ++ abs_y-p-tuning = <200>; ++ abs_y-n-tuning = <200>; ++ ++ abs_rx-p-tuning = <200>; ++ abs_rx-n-tuning = <200>; ++ ++ abs_ry-p-tuning = <200>; ++ abs_ry-n-tuning = <200>; ++ ++ /* poll device interval (ms), adc read interval */ ++ poll-interval = <10>; ++ btn-lr-to-absx; ++ btn-ud-to-absy; ++ ++ /* gpio button auto repeat set value : default disable */ ++ /* ++ autorepeat; ++ */ ++ ++ /* ++ *** MagicX XU10 - layoout *** ++ |-------------------------------| ++ | sw14 sw17 sw16 sw15 | ++ |-----|-------------------|-----| ++ | | | | ++ |vol+ | | sw13| ++ |vol- | | | ++ | | LCD Display | | ++ | | | | ++ | | | | ++ | |-------------------| | ++ | sw9 sw10 | ++ | | ++ | sw1 sw7 | ++ | sw3 sw4 sw8 sw6 | ++ | sw2 sw5 | ++ | | ++ | sw11 sw12 | ++ | | ++ |-------|---------------|-------| ++ */ ++ ++ /* ++ joypad driver is poll-device driver. ++ poll-device is does not support wakeup-source. ++ */ ++ ++ sw1 { + gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; + label = "GPIO DPAD-UP"; + linux,code = ; // 0x220 @@ -565,21 +1219,21 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; -+ charge-term-current-microamp = <300000>; -+ constant-charge-current-max-microamp = <2000000>; ++ charge-term-current-microamp = <200000>; ++ constant-charge-current-max-microamp = <1500000>; + constant-charge-voltage-max-microvolt = <4200000>; -+ factory-internal-resistance-micro-ohms = <134000>; ++ factory-internal-resistance-micro-ohms = <100000>; + voltage-max-design-microvolt = <4100000>; -+ voltage-min-design-microvolt = <3500000>; ++ voltage-min-design-microvolt = <3300000>; + + ocv-capacity-celsius = <20>; + ocv-capacity-table-0 = -+ <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, -+ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, -+ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, -+ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, -+ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, -+ <3574170 0>; ++ <4046950 100>, <4001920 95>, <3967900 90>, <3940000 85>, ++ <3910000 80>, <3870000 75>, <3830000 70>, <3790000 65>, ++ <3750000 60>, <3720000 55>, <3690000 50>, <3650000 45>, ++ <3610000 40>, <3570000 35>, <3540000 30>, <3500000 25>, ++ <3460000 20>, <3420000 15>, <3380000 10>, <3340000 5>, ++ <3300000 0>; + }; + + gpio-keys-vol { @@ -601,40 +1255,33 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + }; + }; + -+ /* led-1 is wired directly to output of always-on regulator */ -+ + leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + -+ green_led: led-0 { -+ color = ; -+ default-state = "on"; -+ function = LED_FUNCTION_POWER; -+ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ amber_led: led-1 { -+ color = ; ++ led-0 { ++ color = ; ++ default-state = "off"; + function = LED_FUNCTION_CHARGING; -+ gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; -+ retain-state-suspended; ++ gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + }; + -+ red_led: led-2 { -+ color = ; ++ led-1 { ++ color = ; + default-state = "off"; + function = LED_FUNCTION_STATUS; -+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; ++ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_det>; + simple-audio-card,name = "rk817_int"; + simple-audio-card,format = "i2s"; -+ simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_LOW>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", @@ -785,7 +1432,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <1350000>; ++ regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; @@ -900,13 +1547,13 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + + vcc_sd: LDO_REG6 { + regulator-name = "vcc_sd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; ++ regulator-suspend-microvolt = <3000000>; + }; + }; + @@ -1003,7 +1650,6 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li +}; + +&sdmmc { -+ bus-width = <4>; + cap-sd-highspeed; + card-detect-delay = <200>; + cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; /*[> ff370000 PD_SDCARD CD GPIO <]*/ @@ -1017,9 +1663,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li +}; + +&sdio { -+ bus-width = <4>; + cap-sd-highspeed; -+ supports-sd; + card-detect-delay = <200>; + cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ + sd-uhs-sdr12; @@ -1098,16 +1742,15 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + + headphone { + hp_det: hp-det { -+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; ++ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-led { + led_pins: led-pins { + rockchip,pins = -+ <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>, -+ <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>, -+ <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>, ++ <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + @@ -1134,8 +1777,8 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-anbernic-rg351v.dts li + }; +}; diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi 2024-01-17 03:47:10.078350209 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi 2024-01-17 03:59:58.108276677 +0000 +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi 2024-01-29 05:08:22.844542450 +0000 @@ -25,93 +25,40 @@ compatible = "pwm-backlight"; power-supply = <&vcc_bl>; @@ -1268,35 +1911,318 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go.dtsi linux/a }; }; -+&dmc { -+ center-supply = <&vdd_logic>; -+}; -+ - &cpu0 { - cpu-supply = <&vdd_arm>; ++&dmc { ++ center-supply = <&vdd_logic>; ++}; ++ + &cpu0 { + cpu-supply = <&vdd_arm>; + }; +@@ -236,7 +187,6 @@ + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; +- rotation = <270>; + + port { + mipi_in_panel: endpoint { +@@ -271,6 +221,7 @@ + clocks = <&cru SCLK_I2S1_OUT>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; ++ rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + #sound-dai-cells = <0>; +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts 2024-01-29 05:08:22.844542450 +0000 +@@ -16,31 +16,187 @@ + mmc1 = &sdio; + }; + +- analog_sticks: adc-joystick { +- compatible = "adc-joystick"; +- io-channels = <&saradc 1>, +- <&saradc 2>; +- poll-interval = <60>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- axis@0 { +- reg = <0>; +- abs-flat = <10>; +- abs-fuzz = <10>; +- abs-range = <172 772>; +- linux,code = ; +- }; ++ gpio_keys: volume-keys { ++ compatible = "gpio-keys-polled"; ++ poll-interval = <5>; ++ autorepeat; ++ ++ volume-up-button { ++ label = "VOLUME-UP"; ++ linux,code = ; ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; ++ ++ }; ++ volume-down-button { ++ label = "VOLUME-DOWN"; ++ linux,code = ; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + +- axis@1 { +- reg = <1>; +- abs-flat = <10>; +- abs-fuzz = <10>; +- abs-range = <278 815>; +- linux,code = ; + }; + }; + ++ joypad: odroidgo2-joypad { ++ compatible = "odroidgo2-v11-joypad"; ++ ++ /* ++ - odroidgo2-joypad sysfs list - ++ * for poll device interval(ms) ++ /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] ++ * for button-adc-fuzz ++ /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] ++ * for button-adc-flat ++ /sys/devices/platform/odroidgo2_joypad/adc_flat [r] ++ ++ * for report control(1:enable, 0:disable) ++ /sys/devices/platform/odroidgo2_joypad/enable [rw] ++ * for adc calibration value setup(1:current adcs value -> cal value) ++ /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] ++ */ ++ ++ /* gpio pincontrol setup */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&btn_pins>; ++ ++ /* JOY_X, JOY_Y Channel define */ ++ io-channel-names = "joy_x", "joy_y"; ++ io-channels = <&saradc 1>, <&saradc 2>; ++ ++ /* adc channel count */ ++ button-adc-count = <2>; ++ ++ /* adc calculate scale */ ++ button-adc-scale = <2>; ++ ++ /* adc deadzone range */ ++ button-adc-deadzone = <20>; ++ ++ /* ++ joy-stick voltage range ++ /sys/devices/platform/ff288000.saradc/iio:device0 ++ adc-x : in_voltage1_raw ++ adc-y : in_voltage2_raw ++ ++ range calculate. ++ (adc raw max value - adc raw min value) * scale * 1.7515 ++ */ ++ button-adc-x-range = <1800>; ++ button-adc-y-range = <1800>; ++ ++ /* ++ specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ button-adc-fuzz = <32>; ++ button-adc-flat = <32>; ++ ++ /* poll device interval (ms), adc read interval */ ++ poll-interval = <10>; ++ ++ /* gpio button auto repeat set value : default disable */ ++ /* ++ autorepeat; ++ */ ++ ++ /* ++ *** ODROIDGO2-Advance Switch layoout *** ++ |------------------------------------------------| ++ | sw15 sw16 | ++ | sw20 sw21 | ++ |------------------------------------------------| ++ | sw1 |-------------------| sw8 | ++ | sw3 sw4 | | sw7 sw5 | ++ | sw2 | LCD Display | sw6 | ++ | | | | ++ | |-------------------| | ++ | sw9 sw10 vol- vol+ sw13 sw14 | ++ |------------------------------------------------| ++ */ ++ /* ++ joypad driver is poll-device driver. ++ poll-device is does not support wakeup-source. ++ */ ++ sw1 { ++ gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-UP"; ++ linux,code = ; // 0x220 ++ }; ++ sw2 { ++ gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-DOWN"; ++ linux,code = ; // 0x221 ++ }; ++ sw3 { ++ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-LEFT"; ++ linux,code = ; // 0x222 ++ }; ++ sw4 { ++ gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-RIGHT"; ++ linux,code = ; // 0x223 ++ }; ++ sw5 { ++ gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; ++ label = "GPIO KEY BTN-A"; ++ linux,code = ; // 0x131 ++ }; ++ sw6 { ++ gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-B"; ++ linux,code = ; // 0x130 ++ }; ++ sw7 { ++ gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-Y"; ++ linux,code = ; // 0x134 ++ }; ++ sw8 { ++ gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-X"; ++ linux,code = ; // 0x133 ++ }; ++ sw9 { ++ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "GPIO F1"; ++ linux,code = ; // 0x2c0 ++ }; ++ sw10 { ++ gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; ++ label = "GPIO F2"; ++ linux,code = ; // 0x2c1 ++ }; ++ sw13 { ++ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; ++ label = "GPIO F5"; ++ linux,code = ; // 0x2c4 ++ }; ++ sw14 { ++ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "GPIO F6"; ++ linux,code = ; // 0x13c ++ }; ++ sw15 { ++ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT"; ++ linux,code = ; // 0x02 ++ }; ++ sw16 { ++ gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT"; ++ linux,code = ; // 0x05 ++ }; ++ sw20 { ++ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT2"; ++ linux,code = ; ++ }; ++ sw21 { ++ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT2"; ++ linux,code = ; ++ }; ++ }; ++ + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3000000>; +@@ -65,19 +221,8 @@ + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pwrseq_pins>; + reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; +- }; +-}; +- +-&builtin_gamepad { +- button-sw20 { +- gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; +- label = "TOP-LEFT 2"; +- linux,code = ; +- }; +- button-sw21 { +- gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; +- label = "TOP-RIGHT 2"; +- linux,code = ; ++ post-power-on-delay-ms = <300>; ++ power-off-delay-us = <200000>; + }; + }; + +@@ -85,6 +230,7 @@ + compatible = "elida,kd35t133"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; ++ rotation = <270>; }; -@@ -236,7 +187,6 @@ - reg = <0>; - backlight = <&backlight>; - reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; -- rotation = <270>; - port { - mipi_in_panel: endpoint { -@@ -271,6 +221,7 @@ - clocks = <&cru SCLK_I2S1_OUT>; - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>; -+ rockchip,system-power-controller; - wakeup-source; - #clock-cells = <1>; - #sound-dai-cells = <0>; -diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts 2024-01-17 03:47:10.078350209 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts 2024-01-17 03:59:58.108276677 +0000 -@@ -16,31 +16,187 @@ - mmc1 = &sdio; + &rk817 { +@@ -93,9 +239,11 @@ + regulator-name = "vcc_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; + + regulator-state-mem { +- regulator-on-in-suspend; ++ regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; +@@ -112,16 +260,15 @@ + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; +- mmc-pwrseq = <&wifi_pwrseq>; + non-removable; + vmmc-supply = <&vcc_wifi>; +- #address-cells = <1>; +- #size-cells = <0>; ++ mmc-pwrseq = <&wifi_pwrseq>; + status = "okay"; + + esp8089: wifi@1 { + compatible = "esp,esp8089"; + reg = <1>; ++ esp,crystal-26M-en = <1>; }; + }; + +@@ -138,8 +285,6 @@ + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, +- <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, +- <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts 2024-01-29 05:08:22.844542450 +0000 +@@ -12,30 +12,175 @@ + model = "ODROID-GO Advance"; + compatible = "hardkernel,rk3326-odroid-go2", "rockchip,rk3326"; - analog_sticks: adc-joystick { - compatible = "adc-joystick"; @@ -1312,34 +2238,37 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts lin - abs-fuzz = <10>; - abs-range = <172 772>; - linux,code = ; -- }; -+ gpio_keys: volume-keys { -+ compatible = "gpio-keys-polled"; -+ poll-interval = <5>; -+ autorepeat; -+ -+ volume-up-button { -+ label = "VOLUME-UP"; -+ linux,code = ; -+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; -+ -+ }; -+ volume-down-button { -+ label = "VOLUME-DOWN"; -+ linux,code = ; -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; - +- }; +- - axis@1 { - reg = <1>; - abs-flat = <10>; - abs-fuzz = <10>; - abs-range = <278 815>; - linux,code = ; - }; - }; - +- }; +- }; ++ gpio_keys: volume-keys { ++ compatible = "gpio-keys-polled"; ++ poll-interval = <5>; ++ autorepeat; ++ ++ volume-up-button { ++ label = "VOLUME-UP"; ++ linux,code = ; ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; ++ ++ }; ++ volume-down-button { ++ label = "VOLUME-DOWN"; ++ linux,code = ; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ ++ }; ++ }; ++ + joypad: odroidgo2-joypad { -+ compatible = "odroidgo2-v11-joypad"; ++ compatible = "odroidgo2-joypad"; + + /* + - odroidgo2-joypad sysfs list - @@ -1404,7 +2333,6 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts lin + *** ODROIDGO2-Advance Switch layoout *** + |------------------------------------------------| + | sw15 sw16 | -+ | sw20 sw21 | + |------------------------------------------------| + | sw1 |-------------------| sw8 | + | sw3 sw4 | | sw7 sw5 | @@ -1486,105 +2414,105 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2-v11.dts lin + sw16 { + gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-RIGHT"; -+ linux,code = ; // 0x05 -+ }; -+ sw20 { -+ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-LEFT2"; -+ linux,code = ; -+ }; -+ sw21 { -+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT2"; -+ linux,code = ; ++ linux,code = ; // 0x05 + }; + }; -+ + battery: battery { compatible = "simple-battery"; - charge-full-design-microamp-hours = <3000000>; -@@ -65,19 +221,8 @@ - pinctrl-names = "default"; - pinctrl-0 = <&wifi_pwrseq_pins>; - reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; -- }; --}; -- --&builtin_gamepad { -- button-sw20 { -- gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -- label = "TOP-LEFT 2"; -- linux,code = ; -- }; -- button-sw21 { -- gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; -- label = "TOP-RIGHT 2"; -- linux,code = ; -+ post-power-on-delay-ms = <300>; -+ power-off-delay-us = <200000>; - }; - }; - -@@ -85,6 +230,7 @@ +@@ -61,8 +206,30 @@ compatible = "elida,kd35t133"; iovcc-supply = <&vcc_lcd>; vdd-supply = <&vcc_lcd>; + rotation = <270>; }; - &rk817 { -@@ -93,9 +239,11 @@ - regulator-name = "vcc_wifi"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; - - regulator-state-mem { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; -@@ -112,16 +260,15 @@ - cap-sdio-irq; - disable-wp; - keep-power-in-suspend; -- mmc-pwrseq = <&wifi_pwrseq>; - non-removable; - vmmc-supply = <&vcc_wifi>; -- #address-cells = <1>; -- #size-cells = <0>; -+ mmc-pwrseq = <&wifi_pwrseq>; - status = "okay"; - - esp8089: wifi@1 { - compatible = "esp,esp8089"; - reg = <1>; -+ esp,crystal-26M-en = <1>; - }; + &rk817_charger { + monitored-battery = <&battery>; }; ++ ++&pinctrl { ++ btns { ++ btn_pins: btn-pins { ++ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts 2024-01-29 05:07:30.179290843 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts 2024-01-29 05:08:22.844542450 +0000 +@@ -12,67 +12,196 @@ + model = "ODROID-GO Super"; + compatible = "hardkernel,rk3326-odroid-go3", "rockchip,rk3326"; -@@ -138,8 +285,6 @@ - <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, - <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, - <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, -- <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, -- <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, - <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, - <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, - <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, -diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts 2024-01-17 03:47:10.078350209 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts 2024-01-17 03:59:58.108276677 +0000 -@@ -12,30 +12,175 @@ - model = "ODROID-GO Advance"; - compatible = "hardkernel,rk3326-odroid-go2", "rockchip,rk3326"; +- joystick_mux_controller: mux-controller { +- compatible = "gpio-mux"; +- pinctrl = <&mux_en_pins>; +- #mux-control-cells = <0>; ++ joypad: odroidgo3-joypad { ++ compatible = "odroidgo3-joypad"; ++ status = "okay"; ++ /* ++ - odroidgo3-joypad sysfs list - ++ * for poll device interval(ms) ++ /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] ++ ex) echo 20 > poll_interval ++ * for button-adc-fuzz ++ /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] ++ * for button-adc-flat ++ /sys/devices/platform/odroidgo3_joypad/adc_flat [r] ++ ++ * for report control(1:enable, 0:disable) ++ /sys/devices/platform/odroidgo3_joypad/enable [rw] ++ * for adc calibration value setup(current adcs value -> cal value) ++ /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] ++ ex) echo 0 > adc_cal ++ * for amux data debug ++ * Joypad driver is disabled when using this sysfs. ++ /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] ++ ex) echo 0 > amux_debug --> select amux channel ++ ex) cat amux_debug --> get adc data of seleted channel ++ */ ++ ++ /* gpio pincontrol setup */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&btn_pins>; + +- mux-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>, +- <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; +- }; +- +- joystick_mux: adc-mux { +- compatible = "io-channel-mux"; ++ /* Analog mux define */ ++ io-channel-names = "amux_adc"; + io-channels = <&saradc 1>; +- io-channel-names = "parent"; +- #io-channel-cells = <1>; +- +- mux-controls = <&joystick_mux_controller>; +- channels = "0", "1", "2", "3"; +- }; - analog_sticks: adc-joystick { - compatible = "adc-joystick"; -- io-channels = <&saradc 1>, -- <&saradc 2>; +- io-channels = <&joystick_mux 0>, +- <&joystick_mux 1>, +- <&joystick_mux 2>, +- <&joystick_mux 3>; - poll-interval = <60>; - #address-cells = <1>; - #size-cells = <0>; @@ -1593,7 +2521,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/a - reg = <0>; - abs-flat = <10>; - abs-fuzz = <10>; -- abs-range = <172 772>; +- abs-range = <180 800>; - linux,code = ; - }; - @@ -1601,75 +2529,39 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/a - reg = <1>; - abs-flat = <10>; - abs-fuzz = <10>; -- abs-range = <278 815>; +- abs-range = <180 800>; +- linux,code = ; +- }; +- +- axis@2 { +- reg = <2>; +- abs-flat = <10>; +- abs-fuzz = <10>; +- abs-range = <180 800>; - linux,code = ; - }; +- +- axis@3 { +- reg = <3>; +- abs-flat = <10>; +- abs-fuzz = <10>; +- abs-range = <180 800>; +- linux,code = ; +- }; - }; -+ gpio_keys: volume-keys { -+ compatible = "gpio-keys-polled"; -+ poll-interval = <5>; -+ autorepeat; -+ -+ volume-up-button { -+ label = "VOLUME-UP"; -+ linux,code = ; -+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; -+ -+ }; -+ volume-down-button { -+ label = "VOLUME-DOWN"; -+ linux,code = ; -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; -+ -+ }; -+ }; -+ -+ joypad: odroidgo2-joypad { -+ compatible = "odroidgo2-joypad"; -+ -+ /* -+ - odroidgo2-joypad sysfs list - -+ * for poll device interval(ms) -+ /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] -+ * for button-adc-fuzz -+ /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] -+ * for button-adc-flat -+ /sys/devices/platform/odroidgo2_joypad/adc_flat [r] -+ -+ * for report control(1:enable, 0:disable) -+ /sys/devices/platform/odroidgo2_joypad/enable [rw] -+ * for adc calibration value setup(1:current adcs value -> cal value) -+ /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] -+ */ -+ -+ /* gpio pincontrol setup */ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&btn_pins>; -+ -+ /* JOY_X, JOY_Y Channel define */ -+ io-channel-names = "joy_x", "joy_y"; -+ io-channels = <&saradc 1>, <&saradc 2>; -+ -+ /* adc channel count */ -+ button-adc-count = <2>; ++ /* adc mux channel count */ ++ amux-count = <4>; ++ /* adc mux select(a,b) gpio */ ++ amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; ++ amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ /* adc mux enable gpio */ ++ amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ -+ button-adc-deadzone = <20>; -+ -+ /* -+ joy-stick voltage range -+ /sys/devices/platform/ff288000.saradc/iio:device0 -+ adc-x : in_voltage1_raw -+ adc-y : in_voltage2_raw -+ -+ range calculate. -+ (adc raw max value - adc raw min value) * scale * 1.7515 -+ */ -+ button-adc-x-range = <1800>; -+ button-adc-y-range = <1800>; ++ button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from @@ -1678,6 +2570,23 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/a + button-adc-fuzz = <32>; + button-adc-flat = <32>; + ++ /* ++ Analog Stick data tuning value(precent) ++ p = positive direction, n = negative direction ++ report value = (real_adc_data * tuning_value) / 100 ++ */ ++ abs_x-p-tuning = <180>; ++ abs_x-n-tuning = <180>; ++ ++ abs_y-p-tuning = <180>; ++ abs_y-n-tuning = <170>; ++ ++ abs_rx-p-tuning = <180>; ++ abs_rx-n-tuning = <180>; ++ ++ abs_ry-p-tuning = <180>; ++ abs_ry-n-tuning = <170>; ++ + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + @@ -1687,17 +2596,20 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/a + */ + + /* -+ *** ODROIDGO2-Advance Switch layoout *** ++ *** ODROIDGO3-Advance Switch layoout *** + |------------------------------------------------| -+ | sw15 sw16 | ++ | sw15 sw21 sw10 sw9 sw20 sw16 | + |------------------------------------------------| -+ | sw1 |-------------------| sw8 | ++ | sw19 sw22 | ++ | |-------------------| | ++ | sw1 | | sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | ++ | | | | + | |-------------------| | -+ | sw9 sw10 vol- vol+ sw13 sw14 | -+ |------------------------------------------------| ++ | sw11 sw12 | sd-slot | sw13 sw14 | ++ |-------------------| |------------------| + */ + /* + joypad driver is poll-device driver. @@ -1743,15 +2655,15 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/a + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; -+ sw9 { -+ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; -+ label = "GPIO F1"; -+ linux,code = ; // 0x2c0 ++ sw11 { ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ label = "GPIO F3"; ++ linux,code = ; // 0x2c2 + }; -+ sw10 { -+ gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; -+ label = "GPIO F2"; -+ linux,code = ; // 0x2c1 ++ sw12 { ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "GPIO F4"; ++ linux,code = ; // 0x2c3 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; @@ -1773,152 +2685,150 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts linux/a + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; ++ sw19 { ++ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; ++ label = "GPIO F1"; ++ linux,code = ; ++ }; ++ sw20 { ++ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT2"; ++ linux,code = ; ++ }; ++ sw21 { ++ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT2"; ++ linux,code = ; ++ }; ++ sw22 { ++ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; ++ label = "GPIO F2"; ++ linux,code = ; ++ }; + }; battery: battery { compatible = "simple-battery"; -@@ -61,8 +206,30 @@ - compatible = "elida,kd35t133"; - iovcc-supply = <&vcc_lcd>; - vdd-supply = <&vcc_lcd>; +@@ -113,39 +242,12 @@ + }; + }; + +-/* f1 and f2 conflict with volume buttons */ +-/delete-node/ &btn_f1; +-/delete-node/ &btn_f2; +- +-&builtin_gamepad { +- button-sw19 { +- gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; +- label = "SELECT"; +- linux,code = ; +- }; +- /* note that TR2 and TL2 are swapped */ +- button-sw20 { +- gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; +- label = "TOP-RIGHT 2"; +- linux,code = ; +- }; +- button-sw21 { +- gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; +- label = "TOP-LEFT 2"; +- linux,code = ; +- }; +- button-sw22 { +- gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; +- label = "START"; +- linux,code = ; +- }; +-}; +- + &internal_display { + compatible = "elida,kd50t048a", "sitronix,st7701"; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + IOVCC-supply = <&vcc_lcd>; + VCC-supply = <&vcc_lcd>; + rotation = <270>; }; &rk817_charger { - monitored-battery = <&battery>; +@@ -179,10 +281,4 @@ + <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +- +- joystick { +- mux_en_pins: mux-pins { +- rockchip,pins = <3 RK_PB5 RK_FUNC_GPIO &pcfg_output_low>; +- }; +- }; }; +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts linux/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts 1970-01-01 00:00:00.000000000 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts 2024-01-29 05:08:22.844542450 +0000 +@@ -0,0 +1,280 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2019 Hardkernel Co., Ltd ++ * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH ++ * Copyright (c) 2022 Maya Matuszczyk ++ */ ++ ++/dts-v1/; ++#include "rk3326-odroid-go.dtsi" ++ ++/ { ++ model = "Powkiddy RGB10"; ++ compatible = "powkiddy,rk3326-rgb10", "rockchip,rk3326"; ++ ++ aliases { ++ mmc1 = &sdio; ++ }; ++ ++ joypad: odroidgo2-joypad { ++ compatible = "odroidgo2-v11-joypad"; + -+&pinctrl { -+ btns { -+ btn_pins: btn-pins { -+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts 2024-01-17 03:47:10.078350209 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts 2024-01-17 03:59:58.108276677 +0000 -@@ -12,67 +12,196 @@ - model = "ODROID-GO Super"; - compatible = "hardkernel,rk3326-odroid-go3", "rockchip,rk3326"; - -- joystick_mux_controller: mux-controller { -- compatible = "gpio-mux"; -- pinctrl = <&mux_en_pins>; -- #mux-control-cells = <0>; -+ joypad: odroidgo3-joypad { -+ compatible = "odroidgo3-joypad"; -+ status = "okay"; + /* -+ - odroidgo3-joypad sysfs list - ++ - odroidgo2-joypad sysfs list - + * for poll device interval(ms) -+ /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] -+ ex) echo 20 > poll_interval ++ /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] + * for button-adc-fuzz -+ /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] ++ /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] + * for button-adc-flat -+ /sys/devices/platform/odroidgo3_joypad/adc_flat [r] ++ /sys/devices/platform/odroidgo2_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) -+ /sys/devices/platform/odroidgo3_joypad/enable [rw] -+ * for adc calibration value setup(current adcs value -> cal value) -+ /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] -+ ex) echo 0 > adc_cal -+ * for amux data debug -+ * Joypad driver is disabled when using this sysfs. -+ /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] -+ ex) echo 0 > amux_debug --> select amux channel -+ ex) cat amux_debug --> get adc data of seleted channel ++ /sys/devices/platform/odroidgo2_joypad/enable [rw] ++ * for adc calibration value setup(1:current adcs value -> cal value) ++ /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; - -- mux-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>, -- <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; -- }; -- -- joystick_mux: adc-mux { -- compatible = "io-channel-mux"; -+ /* Analog mux define */ -+ io-channel-names = "amux_adc"; - io-channels = <&saradc 1>; -- io-channel-names = "parent"; -- #io-channel-cells = <1>; -- -- mux-controls = <&joystick_mux_controller>; -- channels = "0", "1", "2", "3"; -- }; - -- analog_sticks: adc-joystick { -- compatible = "adc-joystick"; -- io-channels = <&joystick_mux 0>, -- <&joystick_mux 1>, -- <&joystick_mux 2>, -- <&joystick_mux 3>; -- poll-interval = <60>; -- #address-cells = <1>; -- #size-cells = <0>; -- -- axis@0 { -- reg = <0>; -- abs-flat = <10>; -- abs-fuzz = <10>; -- abs-range = <180 800>; -- linux,code = ; -- }; -- -- axis@1 { -- reg = <1>; -- abs-flat = <10>; -- abs-fuzz = <10>; -- abs-range = <180 800>; -- linux,code = ; -- }; -- -- axis@2 { -- reg = <2>; -- abs-flat = <10>; -- abs-fuzz = <10>; -- abs-range = <180 800>; -- linux,code = ; -- }; -- -- axis@3 { -- reg = <3>; -- abs-flat = <10>; -- abs-fuzz = <10>; -- abs-range = <180 800>; -- linux,code = ; -- }; -- }; -+ /* adc mux channel count */ -+ amux-count = <4>; -+ /* adc mux select(a,b) gpio */ -+ amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; -+ amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; -+ /* adc mux enable gpio */ -+ amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; ++ ++ /* JOY_X, JOY_Y Channel define */ ++ io-channel-names = "joy_x", "joy_y"; ++ io-channels = <&saradc 1>, <&saradc 2>; ++ ++ /* adc channel count */ ++ button-adc-count = <2>; + + /* adc calculate scale */ + button-adc-scale = <2>; + -+ /* adc deadzone range */ -+ button-adc-deadzone = <64>; ++ /* adc deadzone range */ ++ button-adc-deadzone = <20>; ++ ++ /* ++ joy-stick voltage range ++ /sys/devices/platform/ff288000.saradc/iio:device0 ++ adc-x : in_voltage1_raw ++ adc-y : in_voltage2_raw ++ ++ range calculate. ++ (adc raw max value - adc raw min value) * scale * 1.7515 ++ */ ++ button-adc-x-range = <1800>; ++ button-adc-y-range = <1800>; + + /* + specifies fuzz value that is used to filter noise from @@ -1927,23 +2837,6 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts linux/a + button-adc-fuzz = <32>; + button-adc-flat = <32>; + -+ /* -+ Analog Stick data tuning value(precent) -+ p = positive direction, n = negative direction -+ report value = (real_adc_data * tuning_value) / 100 -+ */ -+ abs_x-p-tuning = <180>; -+ abs_x-n-tuning = <180>; -+ -+ abs_y-p-tuning = <180>; -+ abs_y-n-tuning = <170>; -+ -+ abs_rx-p-tuning = <180>; -+ abs_rx-n-tuning = <180>; -+ -+ abs_ry-p-tuning = <180>; -+ abs_ry-n-tuning = <170>; -+ + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + @@ -1953,20 +2846,17 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts linux/a + */ + + /* -+ *** ODROIDGO3-Advance Switch layoout *** ++ *** RGB10 Switch layoout *** + |------------------------------------------------| -+ | sw15 sw21 sw10 sw9 sw20 sw16 | ++ | sw15 sw16 | ++ | sw20 sw21 | + |------------------------------------------------| -+ | sw19 sw22 | -+ | |-------------------| | -+ | sw1 | | sw8 | ++ | sw1 sw10 |-------------------| sw13 sw8 | + | sw3 sw4 | | sw7 sw5 | + | sw2 | LCD Display | sw6 | + | | | | -+ | | | | + | |-------------------| | -+ | sw11 sw12 | sd-slot | sw13 sw14 | -+ |-------------------| |------------------| ++ |------------------------------------------------| + */ + /* + joypad driver is poll-device driver. @@ -2012,15 +2902,15 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts linux/a + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; -+ sw11 { -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; -+ label = "GPIO F3"; -+ linux,code = ; // 0x2c2 ++ sw9 { ++ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "GPIO F1"; ++ linux,code = ; // 0x2c0 + }; -+ sw12 { -+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; -+ label = "GPIO F4"; -+ linux,code = ; // 0x2c3 ++ sw10 { ++ gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; ++ label = "GPIO F2"; ++ linux,code = ; // 0x2c1 + }; + sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; @@ -2042,86 +2932,123 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-odroid-go3.dts linux/a + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; -+ sw19 { -+ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; -+ label = "GPIO F1"; -+ linux,code = ; -+ }; + sw20 { -+ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT2"; -+ linux,code = ; -+ }; -+ sw21 { -+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; -+ sw22 { -+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; -+ label = "GPIO F2"; -+ linux,code = ; ++ sw21 { ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT2"; ++ linux,code = ; + }; + }; - - battery: battery { - compatible = "simple-battery"; -@@ -113,39 +242,12 @@ - }; - }; - --/* f1 and f2 conflict with volume buttons */ --/delete-node/ &btn_f1; --/delete-node/ &btn_f2; -- --&builtin_gamepad { -- button-sw19 { -- gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; -- label = "SELECT"; -- linux,code = ; -- }; -- /* note that TR2 and TL2 are swapped */ -- button-sw20 { -- gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; -- label = "TOP-RIGHT 2"; -- linux,code = ; -- }; -- button-sw21 { -- gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; -- label = "TOP-LEFT 2"; -- linux,code = ; -- }; -- button-sw22 { -- gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; -- label = "START"; -- linux,code = ; -- }; --}; -- - &internal_display { - compatible = "elida,kd50t048a", "sitronix,st7701"; - reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; - IOVCC-supply = <&vcc_lcd>; - VCC-supply = <&vcc_lcd>; ++ ++ battery: battery { ++ compatible = "simple-battery"; ++ charge-full-design-microamp-hours = <2800000>; ++ charge-term-current-microamp = <280000>; ++ constant-charge-current-max-microamp = <2000000>; ++ constant-charge-voltage-max-microvolt = <4200000>; ++ factory-internal-resistance-micro-ohms = <180000>; ++ voltage-max-design-microvolt = <4100000>; ++ voltage-min-design-microvolt = <3500000>; ++ ++ ocv-capacity-celsius = <20>; ++ ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, ++ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, ++ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, ++ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, ++ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, ++ <3574170 0>; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_pwrseq_pins>; ++ /*reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;*/ ++ }; ++}; ++ ++&internal_display { ++ compatible = "elida,kd35t133"; ++ iovcc-supply = <&vcc_lcd>; ++ vdd-supply = <&vcc_lcd>; + rotation = <270>; - }; - - &rk817_charger { -@@ -179,10 +281,4 @@ - <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; -- -- joystick { -- mux_en_pins: mux-pins { -- rockchip,pins = <3 RK_PB5 RK_FUNC_GPIO &pcfg_output_low>; -- }; -- }; - }; -diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts linux/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts 1970-01-01 00:00:00.000000000 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts 2024-01-17 03:59:58.108276677 +0000 -@@ -0,0 +1,280 @@ ++}; ++ ++&rk817 { ++ regulators { ++ vcc_wifi: LDO_REG9 { ++ regulator-name = "vcc_wifi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ }; ++}; ++ ++&rk817_charger { ++ monitored-battery = <&battery>; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ non-removable; ++ vmmc-supply = <&vcc_wifi>; ++ status = "okay"; ++ ++ esp8089: wifi@1 { ++ compatible = "esp,esp8089"; ++ reg = <1>; ++ esp,crystal-26M-en = <2>; ++ }; ++}; ++ ++&pinctrl { ++ btns { ++ btn_pins: btn-pins { ++ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ wifi { ++ wifi_pwrseq_pins: wifi-pwrseq-pins { ++ rockchip,pins = /*<3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,*/ ++ <3 RK_PB6 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ }; ++}; +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb20s.dts linux/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb20s.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb20s.dts 1970-01-01 00:00:00.000000000 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb20s.dts 2024-01-29 20:21:55.821942737 +0000 +@@ -0,0 +1,340 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Hardkernel Co., Ltd @@ -2132,60 +3059,101 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts lin +/dts-v1/; +#include "rk3326-odroid-go.dtsi" + -+/ { -+ model = "Powkiddy RGB10"; -+ compatible = "powkiddy,rk3326-rgb10", "rockchip,rk3326"; ++/ { ++ model = "Powkiddy RGB20S"; ++ compatible = "powkiddy,rgb20s", "rockchip,rk3326"; ++ ++ aliases { ++ mmc0 = &sdio; ++ mmc1 = &sdmmc; ++ }; ++ ++ gpio-keys-vol { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-0 = <&btn_pins_vol>; ++ pinctrl-names = "default"; ++ ++ button-vol-down { ++ gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; ++ label = "VOLUMEDOWN"; ++ linux,code = ; ++ }; ++ ++ button-volume-up { ++ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "VOLUMEUP"; ++ linux,code = ; ++ }; ++ }; ++ ++ joypad: rgb20s-joypad { ++ compatible = "rgb20s-joypad"; + -+ aliases { -+ mmc1 = &sdio; -+ }; ++ pwms = <&pwm0 0 200000000 0>; ++ pwm-names = "enable"; ++ rumble-boost-weak = <0x0000>; ++ rumble-boost-strong = <0x0000>; + -+ joypad: odroidgo2-joypad { -+ compatible = "odroidgo2-v11-joypad"; ++ joypad-name = "RGB20S Gamepad"; ++ joypad-product = <0x1177>; ++ joypad-revision = <0x0177>; + ++ status = "okay"; + /* -+ - odroidgo2-joypad sysfs list - ++ - odroidgo3-joypad sysfs list - + * for poll device interval(ms) -+ /sys/devices/platform/odroidgo2_joypad/poll_interval [rw] ++ /sys/devices/platform/odroidgo3_joypad/poll_interval [rw] ++ ex) echo 20 > poll_interval + * for button-adc-fuzz -+ /sys/devices/platform/odroidgo2_joypad/adc_fuzz [r] ++ /sys/devices/platform/odroidgo3_joypad/adc_fuzz [r] + * for button-adc-flat -+ /sys/devices/platform/odroidgo2_joypad/adc_flat [r] ++ /sys/devices/platform/odroidgo3_joypad/adc_flat [r] + + * for report control(1:enable, 0:disable) -+ /sys/devices/platform/odroidgo2_joypad/enable [rw] -+ * for adc calibration value setup(1:current adcs value -> cal value) -+ /sys/devices/platform/odroidgo2_joypad/adc_cal [rw] ++ /sys/devices/platform/odroidgo3_joypad/enable [rw] ++ * for adc calibration value setup(current adcs value -> cal value) ++ /sys/devices/platform/odroidgo3_joypad/adc_cal [rw] ++ ex) echo 0 > adc_cal ++ ++ * for rumble period(ns) ++ /sys/devices/platform/odroidgo3_joypad/rumble_period ++ ex) echo 20000000 > rumble_duty_cycle ++ ex) cat rumble_duty_cycle -->get current duty cycle ++ ++ * for rumble boost(0~65535) ++ /sys/devices/platform/odroidgo3_joypad/rumble_boost_weak ++ /sys/devices/platform/odroidgo3_joypad/rumble_boost_strong ++ ++ * for amux data debug ++ * Joypad driver is disabled when using this sysfs. ++ /sys/devices/platform/odroidgo3_joypad/amux_debug [rw] ++ ex) echo 0 > amux_debug --> select amux channel ++ ex) cat amux_debug --> get adc data of seleted channel + */ + + /* gpio pincontrol setup */ + pinctrl-names = "default"; + pinctrl-0 = <&btn_pins>; ++ pinctrl-1 = <&pwm0_pin>; + -+ /* JOY_X, JOY_Y Channel define */ -+ io-channel-names = "joy_x", "joy_y"; -+ io-channels = <&saradc 1>, <&saradc 2>; ++ /* Analog mux define */ ++ io-channel-names = "amux_adc"; ++ io-channels = <&saradc 1>; + -+ /* adc channel count */ -+ button-adc-count = <2>; ++ /* adc mux channel count */ ++ amux-count = <4>; ++ /* adc mux select(a,b) gpio */ ++ amux-a-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; ++ amux-b-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ /* adc mux enable gpio */ ++ amux-en-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + + /* adc calculate scale */ + button-adc-scale = <2>; + + /* adc deadzone range */ -+ button-adc-deadzone = <20>; -+ -+ /* -+ joy-stick voltage range -+ /sys/devices/platform/ff288000.saradc/iio:device0 -+ adc-x : in_voltage1_raw -+ adc-y : in_voltage2_raw -+ -+ range calculate. -+ (adc raw max value - adc raw min value) * scale * 1.7515 -+ */ -+ button-adc-x-range = <1800>; -+ button-adc-y-range = <1800>; ++ button-adc-deadzone = <64>; + + /* + specifies fuzz value that is used to filter noise from @@ -2194,27 +3162,35 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts lin + button-adc-fuzz = <32>; + button-adc-flat = <32>; + ++ /* ++ Analog Stick data tuning value(precent) ++ p = positive direction, n = negative direction ++ report value = (real_adc_data * tuning_value) / 100 ++ */ ++ abs_x-p-tuning = <200>; ++ abs_x-n-tuning = <200>; ++ ++ abs_y-p-tuning = <200>; ++ abs_y-n-tuning = <200>; ++ ++ abs_rx-p-tuning = <200>; ++ abs_rx-n-tuning = <200>; ++ ++ abs_ry-p-tuning = <200>; ++ abs_ry-n-tuning = <200>; ++ + /* poll device interval (ms), adc read interval */ + poll-interval = <10>; + ++ /* required for RG351MP */ ++ invert-absx; ++ invert-absy; ++ + /* gpio button auto repeat set value : default disable */ + /* + autorepeat; + */ + -+ /* -+ *** RGB10 Switch layoout *** -+ |------------------------------------------------| -+ | sw15 sw16 | -+ | sw20 sw21 | -+ |------------------------------------------------| -+ | sw1 sw10 |-------------------| sw13 sw8 | -+ | sw3 sw4 | | sw7 sw5 | -+ | sw2 | LCD Display | sw6 | -+ | | | | -+ | |-------------------| | -+ |------------------------------------------------| -+ */ + /* + joypad driver is poll-device driver. + poll-device is does not support wakeup-source. @@ -2259,17 +3235,17 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts lin + label = "GPIO BTN-X"; + linux,code = ; // 0x133 + }; -+ sw9 { -+ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; -+ label = "GPIO F1"; -+ linux,code = ; // 0x2c0 ++ sw11 { ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ label = "GPIO F3"; ++ linux,code = ; // 0x2c2 + }; -+ sw10 { -+ gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; -+ label = "GPIO F2"; -+ linux,code = ; // 0x2c1 ++ sw12 { ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "GPIO F4"; ++ linux,code = ; // 0x2c3 + }; -+ sw13 { ++ /*sw13 { + gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>; + label = "GPIO F5"; + linux,code = ; // 0x2c4 @@ -2278,7 +3254,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts lin + gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO F6"; + linux,code = ; // 0x13c -+ }; ++ };*/ + sw15 { + gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT"; @@ -2289,116 +3265,127 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3326-powkiddy-rgb10.dts lin + label = "GPIO TOP-RIGHT"; + linux,code = ; // 0x05 + }; ++ sw19 { ++ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; ++ label = "GPIO F1"; ++ linux,code = ; ++ }; + sw20 { -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT2"; ++ linux,code = ; ++ }; ++ sw21 { ++ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "GPIO TOP-LEFT2"; + linux,code = ; + }; -+ sw21 { -+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT2"; -+ linux,code = ; ++ sw22 { ++ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; ++ label = "GPIO F2"; ++ linux,code = ; + }; + }; + -+ battery: battery { -+ compatible = "simple-battery"; -+ charge-full-design-microamp-hours = <2800000>; -+ charge-term-current-microamp = <280000>; -+ constant-charge-current-max-microamp = <2000000>; -+ constant-charge-voltage-max-microvolt = <4200000>; -+ factory-internal-resistance-micro-ohms = <180000>; -+ voltage-max-design-microvolt = <4100000>; -+ voltage-min-design-microvolt = <3500000>; -+ -+ ocv-capacity-celsius = <20>; -+ ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, -+ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, -+ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, -+ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, -+ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, -+ <3574170 0>; -+ }; ++ battery: battery { ++ compatible = "simple-battery"; ++ charge-full-design-microamp-hours = <3500000>; ++ charge-term-current-microamp = <350000>; ++ constant-charge-current-max-microamp = <2000000>; ++ constant-charge-voltage-max-microvolt = <4200000>; ++ factory-internal-resistance-micro-ohms = <180000>; ++ voltage-max-design-microvolt = <4100000>; ++ voltage-min-design-microvolt = <3500000>; + -+ wifi_pwrseq: wifi-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_pwrseq_pins>; -+ /*reset-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;*/ -+ }; ++ ocv-capacity-celsius = <20>; ++ ocv-capacity-table-0 = <4046950 100>, <4001920 95>, <3967900 90>, <3919950 85>, ++ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, ++ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, ++ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, ++ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, ++ <3574170 0>; ++ }; +}; + ++/* conflicts with pwm vibration motor */ ++/delete-node/ &vcc_host; ++ ++/* Device only has 1 LED compared to Odroid Go Advance */ ++/delete-node/ &gpio_led; ++ +&internal_display { -+ compatible = "elida,kd35t133"; ++// compatible = "anbernic,rg351v-panel", "newvision,nv3051d"; ++ compatible = "powkiddy,rk2023-panel", "newvision,nv3051d"; + iovcc-supply = <&vcc_lcd>; + vdd-supply = <&vcc_lcd>; -+ rotation = <270>; +}; + -+&rk817 { -+ regulators { -+ vcc_wifi: LDO_REG9 { -+ regulator-name = "vcc_wifi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; ++&io_domains { ++ vccio1-supply = <&vccio_sd>; ++}; + -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ }; ++/delete-node/ &pwm_led; ++ ++&pwm0 { ++ status = "okay"; +}; + ++/delete-node/ &pwm3; ++ +&rk817_charger { -+ monitored-battery = <&battery>; ++ /* This device does not have a current sense resistor */ ++ rockchip,resistor-sense-micro-ohms = <0>; ++ monitored-battery = <&battery>; +}; + +&sdio { -+ bus-width = <4>; + cap-sd-highspeed; -+ cap-sdio-irq; -+ disable-wp; -+ keep-power-in-suspend; -+ non-removable; -+ vmmc-supply = <&vcc_wifi>; ++ card-detect-delay = <200>; ++ cd-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; + status = "okay"; ++}; + -+ esp8089: wifi@1 { -+ compatible = "esp,esp8089"; -+ reg = <1>; -+ esp,crystal-26M-en = <2>; -+ }; ++&vcc_sd { ++ regulator-max-microvolt = <3000000>; ++ regulator-min-microvolt = <1800000>; ++}; ++ ++&vccio_sd { ++ regulator-max-microvolt = <1800000>; +}; + +&pinctrl { -+ btns { ++ btns { ++ btn_pins_vol: btn-pins-vol { ++ rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ + btn_pins: btn-pins { -+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, -+ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, ++ rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, -+ <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; -+ }; -+ -+ wifi { -+ wifi_pwrseq_pins: wifi-pwrseq-pins { -+ rockchip,pins = /*<3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,*/ -+ <3 RK_PB6 RK_FUNC_GPIO &pcfg_output_high>; -+ }; -+ }; ++ }; +}; diff --git a/projects/Rockchip/packages/linux/patches/RK3326/001-panel-updates.patch b/projects/Rockchip/packages/linux/patches/RK3326/001-panel-updates.patch index 47d9b86132..fd554be65f 100644 --- a/projects/Rockchip/packages/linux/patches/RK3326/001-panel-updates.patch +++ b/projects/Rockchip/packages/linux/patches/RK3326/001-panel-updates.patch @@ -1,7 +1,7 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-elida-kd35t133.c linux/drivers/gpu/drm/panel/panel-elida-kd35t133.c ---- linux.orig/drivers/gpu/drm/panel/panel-elida-kd35t133.c 2024-01-17 03:47:11.674388741 +0000 -+++ linux/drivers/gpu/drm/panel/panel-elida-kd35t133.c 2024-01-17 04:02:49.500183606 +0000 -@@ -107,6 +107,8 @@ static int kd35t133_unprepare(struct drm +--- linux.orig/drivers/gpu/drm/panel/panel-elida-kd35t133.c 2024-01-29 19:42:59.344227350 +0000 ++++ linux/drivers/gpu/drm/panel/panel-elida-kd35t133.c 2024-01-29 19:46:14.500635108 +0000 +@@ -109,6 +109,8 @@ static int kd35t133_unprepare(struct drm regulator_disable(ctx->iovcc); regulator_disable(ctx->vdd); @@ -11,17 +11,17 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-elida-kd35t133.c linux/drivers return 0; diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/drivers/gpu/drm/panel/panel-newvision-nv3051d.c ---- linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c 2024-01-17 03:47:11.678388835 +0000 -+++ linux/drivers/gpu/drm/panel/panel-newvision-nv3051d.c 2024-01-17 04:02:49.500183606 +0000 +--- linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c 2024-01-29 19:42:59.344227350 +0000 ++++ linux/drivers/gpu/drm/panel/panel-newvision-nv3051d.c 2024-01-29 21:01:52.715952484 +0000 @@ -28,6 +28,7 @@ struct nv3051d_panel_info { unsigned int num_modes; u16 width_mm, height_mm; u32 bus_flags; -+ unsigned long mode_flags; ++ u32 mode_flags; }; struct panel_nv3051d { -@@ -385,15 +386,7 @@ static int panel_nv3051d_probe(struct mi +@@ -387,15 +388,7 @@ static int panel_nv3051d_probe(struct mi dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; @@ -38,7 +38,40 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv drm_panel_init(&ctx->panel, &dsi->dev, &panel_nv3051d_funcs, DRM_MODE_CONNECTOR_DSI); -@@ -487,10 +480,24 @@ static const struct nv3051d_panel_info n +@@ -483,16 +476,57 @@ static const struct drm_display_mode nv3 + }, + }; + +-static const struct nv3051d_panel_info nv3051d_rgxx3_info = { ++static const struct drm_display_mode nv3051d_rk2023_modes[] = { ++ { ++ .hdisplay = 640, ++ .hsync_start = 640 + 48, ++ .hsync_end = 640 + 48 + 2, ++ .htotal = 640 + 48 + 2 + 47, ++ .vdisplay = 480, ++ .vsync_start = 480 + 2, ++ .vsync_end = 480 + 2 + 4, ++ .vtotal = 480 + 2 + 4 + 3, ++ .clock = 21600, ++ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, ++ } ++}; ++ ++static const struct nv3051d_panel_info nv3051d_rg351v_info = { ++ .display_modes = nv3051d_rgxx3_modes, ++ .num_modes = ARRAY_SIZE(nv3051d_rgxx3_modes), ++ .width_mm = 70, ++ .height_mm = 57, ++ .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, ++ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET | ++ MIPI_DSI_CLOCK_NON_CONTINUOUS, ++}; ++ ++static const struct nv3051d_panel_info nv3051d_rg353p_info = { + .display_modes = nv3051d_rgxx3_modes, + .num_modes = ARRAY_SIZE(nv3051d_rgxx3_modes), .width_mm = 70, .height_mm = 57, .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, @@ -46,9 +79,9 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET, +}; + -+static const struct nv3051d_panel_info nv3051d_rg351v_info = { -+ .display_modes = nv3051d_rgxx3_modes, -+ .num_modes = ARRAY_SIZE(nv3051d_rgxx3_modes), ++static const struct nv3051d_panel_info nv3051d_rk2023_info = { ++ .display_modes = nv3051d_rk2023_modes, ++ .num_modes = ARRAY_SIZE(nv3051d_rk2023_modes), + .width_mm = 70, + .height_mm = 57, + .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, @@ -58,13 +91,16 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv }; static const struct of_device_id newvision_nv3051d_of_match[] = { - { .compatible = "newvision,nv3051d", .data = &nv3051d_rgxx3_info }, +- { .compatible = "newvision,nv3051d", .data = &nv3051d_rgxx3_info }, + { .compatible = "anbernic,rg351v-panel", .data = &nv3051d_rg351v_info }, ++ { .compatible = "anbernic,rg353p-panel", .data = &nv3051d_rg353p_info }, ++ { .compatible = "powkiddy,rk2023-panel", .data = &nv3051d_rk2023_info }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, newvision_nv3051d_of_match); ---- linux.orig/drivers/gpu/drm/panel/panel-sitronix-st7703.c 2024-01-17 13:11:54.938356637 -0500 -+++ linux/drivers/gpu/drm/panel/panel-sitronix-st7703.c 2024-01-17 12:48:04.770060000 -0500 +diff -rupN linux.orig/drivers/gpu/drm/panel/panel-sitronix-st7703.c linux/drivers/gpu/drm/panel/panel-sitronix-st7703.c +--- linux.orig/drivers/gpu/drm/panel/panel-sitronix-st7703.c 2024-01-29 19:42:59.348227440 +0000 ++++ linux/drivers/gpu/drm/panel/panel-sitronix-st7703.c 2024-01-29 19:46:14.500635108 +0000 @@ -13,7 +13,7 @@ #include #include @@ -404,7 +440,7 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv .hdisplay = 640, .hsync_start = 640 + 40, .hsync_end = 640 + 40 + 2, -@@ -424,15 +452,117 @@ static const struct drm_display_mode rg3 +@@ -424,15 +452,210 @@ static const struct drm_display_mode rg3 .height_mm = 57, }; @@ -500,8 +536,8 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv + .vtotal = 480 + 17 + 4 + 13, + .clock = 30000, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, -+ .width_mm = 70, -+ .height_mm = 52, ++ .width_mm = 52, ++ .height_mm = 70, +}; + +static const struct st7703_panel_desc xu10_desc = { @@ -514,6 +550,99 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv + .init_sequence = xu10_init_sequence, }; ++static int r36s_init_sequence(struct st7703 *ctx) ++{ ++ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); ++ ++ /* ++ * Init sequence was supplied by the panel vendor. ++ */ ++ ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETAPID, 0x00, 0x00, 0x00, ++ 0xda, 0x80); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x00, 0x13, 0x70); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, ++ 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x7f, 0x7f); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x26, 0x62, ++ 0xf0, 0x63); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, ++ 0xf9, 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, ++ 0x00, 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x47); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, ++ 0x00, 0x00, 0x12, 0x50, 0x00); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x53, 0xc0, 0x32, ++ 0x32, 0x77, 0xe1, 0xdd, 0xdd, 0x77, 0x77, 0x33, ++ 0x33); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETECO, 0x82, 0x00, 0xbf, 0xff, ++ 0x00, 0xff); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETIO, 0xb8, 0x00, 0x0a, 0x00, ++ 0x00, 0x00); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETCABC, 0x10, 0x40, 0x1e, ++ 0x02); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x07, 0x0d, ++ 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, 0x0d, ++ 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a, 0x00, 0x07, ++ 0x0d, 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, ++ 0x0d, 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, ++ 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, ++ 0xc0, 0x10); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x02, 0x00, ++ 0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x80, ++ 0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00, ++ 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, ++ 0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88, ++ 0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35, ++ 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, ++ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00); ++ dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02, ++ 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x81, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88, ++ 0x88, 0x88, 0x88, 0x80, 0x88, 0xba, 0x06, 0x42, ++ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, ++ 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00); ++ ++ dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_EF, 0xff, 0xff, 0x01, 0x05, 0xc8, 0x01, 0x11, 0x05, 0x32, 0x01, 0x29); ++ ++ return 0; ++} ++ ++static const struct drm_display_mode r36s_mode = { ++ .hdisplay = 640, ++ .hsync_start = 640 + 450, ++ .hsync_end = 640 + 450 + 70, ++ .htotal = 640 + 450 + 70 + 450, ++ .vdisplay = 480, ++ .vsync_start = 480 + 17, ++ .vsync_end = 480 + 17 + 5, ++ .vtotal = 480 + 17 + 5 + 13, ++ .clock = 50000, ++ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, ++ .width_mm = 52, ++ .height_mm = 70, ++}; ++ ++static const struct st7703_panel_desc r36s_desc = { ++ .mode = &r36s_mode, ++ .lanes = 4, ++ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, ++ .format = MIPI_DSI_FMT_RGB888, ++ .init_sequence = r36s_init_sequence, ++}; ++ +#define dsi_generic_write_seq(dsi, seq...) do { \ + static const u8 d[] = { seq }; \ + int ret; \ @@ -525,7 +654,7 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv static int rgb30panel_init_sequence(struct st7703 *ctx) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); -@@ -446,31 +576,31 @@ static int rgb30panel_init_sequence(stru +@@ -446,31 +669,31 @@ static int rgb30panel_init_sequence(stru mipi_dsi_dcs_exit_sleep_mode(dsi); msleep(250); @@ -572,7 +701,7 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv 0x0f, 0xa1, 0x80, 0x12, 0x31, 0x23, 0x47, 0x86, 0xa1, 0x80, 0x47, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, -@@ -479,7 +609,7 @@ static int rgb30panel_init_sequence(stru +@@ -479,7 +702,7 @@ static int rgb30panel_init_sequence(stru 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); @@ -581,7 +710,7 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv 0x01, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x31, 0x8b, 0xa8, 0x31, 0x75, 0x88, 0x88, 0x88, 0x88, 0x88, 0x4f, 0x20, 0x8b, 0xa8, 0x20, -@@ -488,7 +618,7 @@ static int rgb30panel_init_sequence(stru +@@ -488,7 +711,7 @@ static int rgb30panel_init_sequence(stru 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xa1, 0x80, 0x00, 0x00, 0x00, 0x00); @@ -590,7 +719,7 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, 0x10, 0x13, 0x15, 0x14, 0x15, 0x10, 0x17, 0x00, 0x0a, 0x0f, 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, -@@ -667,7 +797,7 @@ static int allpixelson_set(void *data, u +@@ -667,7 +890,7 @@ static int allpixelson_set(void *data, u struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); dev_dbg(ctx->dev, "Setting all pixels on\n"); @@ -599,17 +728,18 @@ diff -rupN linux.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c linux/driv msleep(val * 1000); /* Reset the panel to get video back */ drm_panel_disable(&ctx->panel); -@@ -783,7 +913,8 @@ static void st7703_remove(struct mipi_ds +@@ -783,7 +1006,9 @@ static void st7703_remove(struct mipi_ds } static const struct of_device_id st7703_of_match[] = { - { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc }, ++ { .compatible = "gameconsole,r36s-panel", .data = &r36s_desc }, + { .compatible = "magicx,xu10-panel", .data = &xu10_desc }, + { .compatible = "anbernic,rg351v-panel-v2", .data = &rg351v2_desc }, { .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc }, { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, { .compatible = "xingbangda,xbd599", .data = &xbd599_desc }, -@@ -802,6 +933,6 @@ static struct mipi_dsi_driver st7703_dri +@@ -802,6 +1027,6 @@ static struct mipi_dsi_driver st7703_dri }; module_mipi_dsi_driver(st7703_driver); diff --git a/projects/Rockchip/packages/linux/patches/RK3326/004-input-drivers.patch b/projects/Rockchip/packages/linux/patches/RK3326/004-input-drivers.patch index 08dce1fbaa..ddbea2e157 100644 --- a/projects/Rockchip/packages/linux/patches/RK3326/004-input-drivers.patch +++ b/projects/Rockchip/packages/linux/patches/RK3326/004-input-drivers.patch @@ -1,6 +1,6 @@ diff -rupN linux.orig/drivers/gpio/gpiolib-of.c linux/drivers/gpio/gpiolib-of.c ---- linux.orig/drivers/gpio/gpiolib-of.c 2024-01-17 03:47:10.962371554 +0000 -+++ linux/drivers/gpio/gpiolib-of.c 2024-01-17 04:04:33.550547556 +0000 +--- linux.orig/drivers/gpio/gpiolib-of.c 2024-01-29 06:18:08.163711909 +0000 ++++ linux/drivers/gpio/gpiolib-of.c 2024-01-29 06:19:30.953540557 +0000 @@ -25,21 +25,6 @@ #include "gpiolib.h" #include "gpiolib-of.h" @@ -45,8 +45,8 @@ diff -rupN linux.orig/drivers/gpio/gpiolib-of.c linux/drivers/gpio/gpiolib-of.c * of_get_named_gpio() - Get a GPIO number to use with GPIO API * @np: device node to get GPIO from diff -rupN linux.orig/drivers/input/Kconfig linux/drivers/input/Kconfig ---- linux.orig/drivers/input/Kconfig 2024-01-17 03:47:11.898394148 +0000 -+++ linux/drivers/input/Kconfig 2024-01-17 04:04:33.550547556 +0000 +--- linux.orig/drivers/input/Kconfig 2024-01-29 06:18:08.495719572 +0000 ++++ linux/drivers/input/Kconfig 2024-01-29 06:19:30.953540557 +0000 @@ -51,6 +51,19 @@ config INPUT_FF_MEMLESS To compile this driver as a module, choose M here: the module will be called ff-memless. @@ -68,8 +68,8 @@ diff -rupN linux.orig/drivers/input/Kconfig linux/drivers/input/Kconfig tristate "Sparse keymap support library" help diff -rupN linux.orig/drivers/input/Makefile linux/drivers/input/Makefile ---- linux.orig/drivers/input/Makefile 2024-01-17 03:47:11.898394148 +0000 -+++ linux/drivers/input/Makefile 2024-01-17 04:04:33.550547556 +0000 +--- linux.orig/drivers/input/Makefile 2024-01-29 06:18:08.495719572 +0000 ++++ linux/drivers/input/Makefile 2024-01-29 06:19:30.953540557 +0000 @@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o i input-core-y += touchscreen.o @@ -80,7 +80,7 @@ diff -rupN linux.orig/drivers/input/Makefile linux/drivers/input/Makefile obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o diff -rupN linux.orig/drivers/input/input-polldev.c linux/drivers/input/input-polldev.c --- linux.orig/drivers/input/input-polldev.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/input-polldev.c 2024-01-17 04:04:33.550547556 +0000 ++++ linux/drivers/input/input-polldev.c 2024-01-29 06:19:30.953540557 +0000 @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* @@ -445,9 +445,9 @@ diff -rupN linux.orig/drivers/input/input-polldev.c linux/drivers/input/input-po +} +EXPORT_SYMBOL(input_unregister_polled_device); diff -rupN linux.orig/drivers/input/joystick/Kconfig linux/drivers/input/joystick/Kconfig ---- linux.orig/drivers/input/joystick/Kconfig 2024-01-17 03:47:11.902394242 +0000 -+++ linux/drivers/input/joystick/Kconfig 2024-01-17 04:07:02.445922624 +0000 -@@ -400,6 +400,26 @@ config JOYSTICK_N64 +--- linux.orig/drivers/input/joystick/Kconfig 2024-01-29 06:18:08.495719572 +0000 ++++ linux/drivers/input/joystick/Kconfig 2024-01-29 06:29:57.539189141 +0000 +@@ -400,6 +400,31 @@ config JOYSTICK_N64 Say Y here if you want enable support for the four built-in controller ports on the Nintendo 64 console. @@ -466,6 +466,11 @@ diff -rupN linux.orig/drivers/input/joystick/Kconfig linux/drivers/input/joystic + help + Made for ODROIDGO3. + ++config JOYSTICK_RGB20S ++ tristate "RGB20S joypad driver" ++ help ++ Made for RGB20S. ++ +config JOYSTICK_XU10 + tristate "XU10 joypad driver" + help @@ -475,19 +480,20 @@ diff -rupN linux.orig/drivers/input/joystick/Kconfig linux/drivers/input/joystic tristate "Raspberry Pi Sense HAT joystick" depends on INPUT && I2C diff -rupN linux.orig/drivers/input/joystick/Makefile linux/drivers/input/joystick/Makefile ---- linux.orig/drivers/input/joystick/Makefile 2024-01-17 03:47:11.902394242 +0000 -+++ linux/drivers/input/joystick/Makefile 2024-01-17 04:14:15.891265883 +0000 -@@ -25,6 +25,9 @@ obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydu +--- linux.orig/drivers/input/joystick/Makefile 2024-01-29 06:18:08.495719572 +0000 ++++ linux/drivers/input/joystick/Makefile 2024-01-29 06:28:09.660788600 +0000 +@@ -25,6 +25,10 @@ obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydu obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o obj-$(CONFIG_JOYSTICK_N64) += n64joy.o +obj-$(CONFIG_JOYSTICK_ODROIDGO2) += odroidgo2-joypad.o +obj-$(CONFIG_JOYSTICK_ODROIDGO2_V11) += odroidgo2-v11-joypad.o +obj-$(CONFIG_JOYSTICK_ODROIDGO3) += odroidgo3-joypad.o ++obj-$(CONFIG_JOYSTICK_RGB20S) += rgb20s-joypad.o obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o -@@ -39,4 +42,5 @@ obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidj +@@ -39,4 +43,5 @@ obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidj obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o obj-$(CONFIG_JOYSTICK_WALKERA0701) += walkera0701.o obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o @@ -495,7 +501,7 @@ diff -rupN linux.orig/drivers/input/joystick/Makefile linux/drivers/input/joysti obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o diff -rupN linux.orig/drivers/input/joystick/odroidgo2-joypad.c linux/drivers/input/joystick/odroidgo2-joypad.c --- linux.orig/drivers/input/joystick/odroidgo2-joypad.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/joystick/odroidgo2-joypad.c 2024-01-17 04:04:33.550547556 +0000 ++++ linux/drivers/input/joystick/odroidgo2-joypad.c 2024-01-29 06:19:30.953540557 +0000 @@ -0,0 +1,878 @@ +/* + * SARADC joystick & GPIO Button driver for Linux(Hardkernel ODROIDGO2-Advance) @@ -1377,7 +1383,7 @@ diff -rupN linux.orig/drivers/input/joystick/odroidgo2-joypad.c linux/drivers/in +/*----------------------------------------------------------------------------*/ diff -rupN linux.orig/drivers/input/joystick/odroidgo2-v11-joypad.c linux/drivers/input/joystick/odroidgo2-v11-joypad.c --- linux.orig/drivers/input/joystick/odroidgo2-v11-joypad.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/joystick/odroidgo2-v11-joypad.c 2024-01-17 04:04:33.550547556 +0000 ++++ linux/drivers/input/joystick/odroidgo2-v11-joypad.c 2024-01-29 06:19:30.953540557 +0000 @@ -0,0 +1,878 @@ +/* + * SARADC joystick & GPIO Button driver for Linux(Hardkernel ODROIDGO2-Advance) @@ -2259,7 +2265,7 @@ diff -rupN linux.orig/drivers/input/joystick/odroidgo2-v11-joypad.c linux/driver +/*----------------------------------------------------------------------------*/ diff -rupN linux.orig/drivers/input/joystick/odroidgo3-joypad.c linux/drivers/input/joystick/odroidgo3-joypad.c --- linux.orig/drivers/input/joystick/odroidgo3-joypad.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/joystick/odroidgo3-joypad.c 2024-01-17 04:04:33.550547556 +0000 ++++ linux/drivers/input/joystick/odroidgo3-joypad.c 2024-01-29 06:19:30.953540557 +0000 @@ -0,0 +1,1086 @@ +/* + * SARADC joystick & GPIO Button driver for Linux(Hardkernel ODROIDGO2-Advance) @@ -3347,8 +3353,1386 @@ diff -rupN linux.orig/drivers/input/joystick/odroidgo3-joypad.c linux/drivers/in +MODULE_ALIAS("platform:" DRV_NAME); + +/*----------------------------------------------------------------------------*/ ---- linux.orig/drivers/input/joystick/xu10-joypad.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux/drivers/input/joystick/xu10-joypad.c 2024-01-18 20:22:15.511207596 -0500 +diff -rupN linux.orig/drivers/input/joystick/rgb20s-joypad.c linux/drivers/input/joystick/rgb20s-joypad.c +--- linux.orig/drivers/input/joystick/rgb20s-joypad.c 1970-01-01 00:00:00.000000000 +0000 ++++ linux/drivers/input/joystick/rgb20s-joypad.c 2024-01-29 06:27:07.151404545 +0000 +@@ -0,0 +1,1373 @@ ++/* ++ * SARADC joystick & GPIO Button driver for Linux(Powkiddy RGB20S) ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to , or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "rgb20s_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++#define ADC_MAX_VOLTAGE 1800 ++#define ADC_DATA_TUNING(x, p) ((x * p) / 100) ++#define ADC_TUNING_DEFAULT 180 ++#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ +--------------------------------+ ++ | IIO Channel : ADC_IN1 | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | EN(GPIO3.B5) | SEL_A(GPIO3.B3) | SEL_B(GPIO3.B0) | SELECT | EVENT | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 0 | 0 | R-Y | ABS_RY | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 0 | 1 | R-X | ABS_RX | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 1 | 0 | L-Y | ABS_Y | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 0 | 1 | 1 | L-X | ABS_X | ++ +--------------+-----------------+-----------------+--------+---------+ ++ | 1 | X | X | XXXX | ++ +--------------+-----------------+-----------------+--------+ ++*/ ++/*----------------------------------------------------------------------------*/ ++struct bt_adc { ++ /* report value (mV) */ ++ int value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++ /* amux channel */ ++ int amux_ch; ++ /* adc data tuning value([percent), p = positive, n = negative */ ++ int tuning_p, tuning_n; ++}; ++ ++struct analog_mux { ++ /* IIO ADC Channel : amux connect channel */ ++ struct iio_channel *iio_ch; ++ /* analog mux select(a,b) gpio */ ++ int sel_a_gpio, sel_b_gpio; ++ /* analog mux enable gpio */ ++ int en_gpio; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* analog mux & joystick control */ ++ struct analog_mux *amux; ++ /* analog mux max count */ ++ int amux_count; ++ /* analog button */ ++ struct bt_adc *adcs; ++ ++ /* report reference point */ ++ bool invert_absx; ++ bool invert_absy; ++ bool invert_absrx; ++ bool invert_absry; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ ++ struct mutex lock; ++ ++ /* amux debug channel */ ++ int debug_ch; ++ ++ /* pwm device for rumble*/ ++ struct input_dev *input; ++ struct pwm_device *pwm; ++ struct work_struct play_work; ++ u16 level; ++ u16 boost_weak; ++ u16 boost_strong; ++}; ++ ++static int pwm_vibrator_start(struct joypad *joypad) ++{ ++ struct device *pdev = joypad->input->dev.parent; ++ struct pwm_state state; ++ int err; ++ ++ pwm_get_state(joypad->pwm, &state); ++ pwm_set_relative_duty_cycle(&state, joypad->level, 0xffff); ++ state.enabled = true; ++ ++ err = pwm_apply_state(joypad->pwm, &state); ++ if (err) { ++ dev_err(pdev, "failed to apply pwm state: %d", err); ++ return err; ++ } ++ ++ return 0; ++} ++ ++static void pwm_vibrator_stop(struct joypad *joypad) ++{ ++ pwm_disable(joypad->pwm); ++} ++ ++static void pwm_vibrator_play_work(struct work_struct *work) ++{ ++ struct joypad *joypad = container_of(work, ++ struct joypad, play_work); ++ ++ if (joypad->level) ++ pwm_vibrator_start(joypad); ++ else ++ pwm_vibrator_stop(joypad); ++} ++ ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_select(struct analog_mux *amux, int channel) ++{ ++ /* select mux channel */ ++ gpio_set_value(amux->en_gpio, 0); ++ ++ switch(channel) { ++ case 0: /* EVENT (ABS_RY) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 1: /* EVENT (ABS_RX) */ ++ gpio_set_value(amux->sel_a_gpio, 0); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ case 2: /* EVENT (ABS_Y) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 0); ++ break; ++ case 3: /* EVENT (ABS_X) */ ++ gpio_set_value(amux->sel_a_gpio, 1); ++ gpio_set_value(amux->sel_b_gpio, 1); ++ break; ++ default: ++ /* amux disanle */ ++ gpio_set_value(amux->en_gpio, 1); ++ return -1; ++ } ++ /* mux swtiching speed : 35ns(on) / 9ns(off) */ ++ usleep_range(1, 2); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct analog_mux *amux, struct bt_adc *adc) ++{ ++ int value; ++ ++ if (joypad_amux_select(amux, adc->amux_ch)) ++ return 0; ++ ++ if (iio_read_channel_processed(amux->iio_ch, &value)) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return value; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d\n", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "adc scale = %d\n", joypad->bt_adc_scale); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/amux_debug [rw] ++ * ++ * echo [debug channel] > amux_debug ++ * cat amux_debug : debug channel mux set & adc read ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ joypad->debug_ch = simple_strtoul(buf, NULL, 10); ++ ++ /* if error than default setting(debug_ch = 0) */ ++ if (joypad->debug_ch > joypad->amux_count) ++ joypad->debug_ch = 0; ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_amux_debug(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ struct analog_mux *amux = joypad->amux; ++ ssize_t pos; ++ int value; ++ ++ mutex_lock(&joypad->lock); ++ ++ /* disable poll driver */ ++ if (joypad->enable) ++ joypad->enable = false; ++ ++ if (joypad_amux_select(amux, joypad->debug_ch)) ++ goto err_out; ++ ++ if (iio_read_channel_processed(amux->iio_ch, &value)) ++ goto err_out; ++ ++ pos = sprintf(buf, "amux ch[%d], adc scale = %d, adc value = %d\n", ++ joypad->debug_ch, joypad->bt_adc_scale, ++ value * joypad->bt_adc_scale); ++ goto out; ++ ++err_out: ++ pos = sprintf(buf, "error : amux setup & adc read!\n"); ++out: ++ mutex_unlock(&joypad->lock); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(amux_debug, S_IWUSR | S_IRUGO, ++ joypad_show_amux_debug, ++ joypad_store_amux_debug); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/rumble_period [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_period(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ pwm_set_period(joypad->pwm, simple_strtoul(buf, NULL, 21)); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_period(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", pwm_get_period(joypad->pwm)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(rumble_period, S_IWUSR | S_IRUGO, ++ joypad_show_period, ++ joypad_store_period); ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/rumble_boost_strong [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_boost_strong(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->boost_strong = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_boost_strong(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->boost_strong); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(rumble_boost_strong, S_IWUSR | S_IRUGO, ++ joypad_show_boost_strong, ++ joypad_store_boost_strong); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/rgb20s_joypad/rumble_boost_weak [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_boost_weak(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->boost_weak = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_boost_weak(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->boost_weak); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(rumble_boost_weak, S_IWUSR | S_IRUGO, ++ joypad_show_boost_weak, ++ joypad_store_boost_weak); ++ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ &dev_attr_amux_debug.attr, ++ &dev_attr_rumble_period.attr, ++ &dev_attr_rumble_boost_strong.attr, ++ &dev_attr_rumble_boost_weak.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->value = adc->value - adc->cal; ++ ++ /* Joystick Deadzone check */ ++ if (joypad->bt_adc_deadzone) { ++ if (abs(adc->value) < joypad->bt_adc_deadzone) ++ adc->value = 0; ++ } ++ ++ /* adc data tuning */ ++ if (adc->tuning_n && adc->value < 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_n); ++ if (adc->tuning_p && adc->value > 0) ++ adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_p); ++ ++ adc->value = adc->value > adc->max ? adc->max : adc->value; ++ adc->value = adc->value < adc->min ? adc->min : adc->value; ++ ++ input_report_abs(poll_dev->input, ++ adc->report_type, ++ adc->invert ? adc->value * (-1) : adc->value); ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad->amux, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ cancel_work_sync(&joypad->play_work); ++ pwm_vibrator_stop(joypad); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_amux_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct analog_mux *amux; ++ enum iio_chan_type type; ++ enum of_gpio_flags flags; ++ int ret; ++ ++ /* analog mux control struct init */ ++ joypad->amux = devm_kzalloc(dev, sizeof(struct analog_mux), ++ GFP_KERNEL); ++ if (!joypad->amux) { ++ dev_err(dev, "%s amux devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ amux = joypad->amux; ++ amux->iio_ch = devm_iio_channel_get(dev, "amux_adc"); ++ if (IS_ERR(amux->iio_ch)) { ++ dev_err(dev, "iio channel get error\n"); ++ return -EINVAL; ++ } ++ if (!amux->iio_ch->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(amux->iio_ch, &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ ++ amux->sel_a_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-a-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_a_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_a_gpio, "amux-sel-a"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-a %d\n", ++ __func__, amux->sel_a_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_a_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->sel_b_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-b-gpios", 0, &flags); ++ if (gpio_is_valid(amux->sel_b_gpio)) { ++ ret = devm_gpio_request(dev, amux->sel_b_gpio, "amux-sel-b"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-sel-b %d\n", ++ __func__, amux->sel_b_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->sel_b_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ ++ amux->en_gpio = of_get_named_gpio_flags(dev->of_node, ++ "amux-en-gpios", 0, &flags); ++ if (gpio_is_valid(amux->en_gpio)) { ++ ret = devm_gpio_request(dev, amux->en_gpio, "amux-en"); ++ if (ret < 0) { ++ dev_err(dev, "%s : failed to request amux-en %d\n", ++ __func__, amux->en_gpio); ++ goto err_out; ++ } ++ ret = gpio_direction_output(amux->en_gpio, 0); ++ if (ret < 0) ++ goto err_out; ++ } ++ return 0; ++err_out: ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn; ++ ++ /* adc button struct init */ ++ joypad->adcs = devm_kzalloc(dev, joypad->amux_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->scale = joypad->bt_adc_scale; ++ ++ adc->max = (ADC_MAX_VOLTAGE / 2); ++ adc->min = (ADC_MAX_VOLTAGE / 2) * (-1); ++ if (adc->scale) { ++ adc->max *= adc->scale; ++ adc->min *= adc->scale; ++ } ++ adc->amux_ch = nbtn; ++ adc->invert = false; ++ ++ switch (nbtn) { ++ case 0: ++ if (joypad->invert_absry) ++ adc->invert = true; ++ adc->report_type = ABS_RY; ++ if (device_property_read_u32(dev, ++ "abs_ry-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_ry-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 1: ++ if (joypad->invert_absrx) ++ adc->invert = true; ++ adc->report_type = ABS_RX; ++ if (device_property_read_u32(dev, ++ "abs_rx-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_rx-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 2: ++ if (joypad->invert_absy) ++ adc->invert = true; ++ adc->report_type = ABS_Y; ++ if (device_property_read_u32(dev, ++ "abs_y-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_y-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 3: ++ if (joypad->invert_absx) ++ adc->invert = true; ++ adc->report_type = ABS_X; ++ if (device_property_read_u32(dev, ++ "abs_x-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_x-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ default : ++ dev_err(dev, "%s amux count(%d) error!", ++ __func__, nbtn); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int rumble_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) ++{ ++ struct joypad *joypad = data; ++ u32 boosted_level; ++ if (effect->type != FF_RUMBLE) ++ return 0; ++ ++ if (effect->u.rumble.strong_magnitude) ++ boosted_level = effect->u.rumble.strong_magnitude + joypad->boost_strong; ++ else ++ boosted_level = effect->u.rumble.weak_magnitude + joypad->boost_weak; ++ ++ joypad->level = (u16)CLAMP(boosted_level, 0, 0xffff); ++ ++ dev_info(joypad->dev,"joypad->level = %d", joypad->level); ++ schedule_work(&joypad->play_work); ++ return 0; ++} ++/*----------------------------------------------------------------------------*/ ++static int joypad_rumble_setup(struct device *dev, struct joypad *joypad) ++{ ++ int err; ++ struct pwm_state state; ++ ++ joypad->pwm = devm_pwm_get(dev, "enable"); ++ if (IS_ERR(joypad->pwm)) ++ { ++ dev_err(dev, "rumble get error\n"); ++ return -EINVAL; ++ } ++ ++ INIT_WORK(&joypad->play_work, pwm_vibrator_play_work); ++ ++ /* Sync up PWM state and ensure it is off. */ ++ pwm_init_state(joypad->pwm, &state); ++ state.enabled = false; ++ err = pwm_apply_state(joypad->pwm, &state); ++ if (err) { ++ dev_err(dev, "failed to apply initial PWM state: %d", ++ err); ++ return err; ++ } ++ dev_info(dev, "rumble setup success!\n"); ++ return 0; ++} ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ u32 joypad_revision = 0; ++ u32 joypad_product = 0; ++ u32 boost_weak = 0; ++ u32 boost_strong = 0; ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ joypad->input = poll_dev->input; ++ ++ device_property_read_string(dev, "joypad-name", &input->name); ++ input->phys = DRV_NAME"/input0"; ++ ++ device_property_read_u32(dev, "joypad-revision", &joypad_revision); ++ device_property_read_u32(dev, "joypad-product", &joypad_product); ++ input->id.bustype = BUS_HOST; ++ input->id.vendor = 0x484B; ++ input->id.product = (u16)joypad_product; ++ input->id.version = (u16)joypad_revision; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ for(nbtn = 0; nbtn < joypad->amux_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ dev_info(dev, ++ "%s : adc tuning_p = %d, adc_tuning_n = %d\n\n", ++ __func__, adc->tuning_p, adc->tuning_n); ++ } ++ ++ /* Rumble setip*/ ++ device_property_read_u32(dev, "rumble-boost-weak", &boost_weak); ++ device_property_read_u32(dev, "rumble-boost-strong", &boost_strong); ++ joypad->boost_weak = boost_weak; ++ joypad->boost_strong = boost_strong; ++ dev_info(dev, "Boost = %d, %d",boost_weak, boost_strong); ++ input_set_capability(input, EV_FF, FF_RUMBLE); ++ error = input_ff_create_memless(input, joypad, rumble_play_effect); ++ if (error) { ++ dev_err(dev, "unable to register rumble, err=%d\n", ++ error); ++ return error; ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ device_property_read_u32(dev, "amux-count", ++ &joypad->amux_count); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ /* change the report reference point? (ADC MAX - read value) */ ++ joypad->invert_absx = device_property_present(dev, "invert-absx"); ++ joypad->invert_absy = device_property_present(dev, "invert-absy"); ++ joypad->invert_absrx = device_property_present(dev, "invert-absrx"); ++ joypad->invert_absry = device_property_present(dev, "invert-absry"); ++ dev_info(dev, "%s : invert-absx = %d, inveret-absy = %d, invert-absrx = %d, inveret-absry = %d\n", ++ __func__, joypad->invert_absx, joypad->invert_absy, joypad->invert_absrx, joypad->invert_absry); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->amux_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->amux_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_amux_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ dev_info(dev, "%s : adc key cnt = %d, gpio key cnt = %d\n", ++ __func__, joypad->amux_count, joypad->bt_gpio_count); ++ ++ return error; ++} ++ ++static int __maybe_unused joypad_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ cancel_work_sync(&joypad->play_work); ++ if (joypad->level) ++ pwm_vibrator_stop(joypad); ++ ++ return 0; ++} ++ ++static int __maybe_unused joypad_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ if (joypad->level) ++ pwm_vibrator_start(joypad); ++ ++ return 0; ++} ++ ++static SIMPLE_DEV_PM_OPS(joypad_pm_ops, ++ joypad_suspend, joypad_resume); ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ ++ /* rumble setup */ ++ error = joypad_rumble_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "rumble setup failed!(err = %d)\n", error); ++ return error; ++ } ++ ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "rgb20s-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .pm = &joypad_pm_ops, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for Powkiddy RGB20S"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ +diff -rupN linux.orig/drivers/input/joystick/xu10-joypad.c linux/drivers/input/joystick/xu10-joypad.c +--- linux.orig/drivers/input/joystick/xu10-joypad.c 1970-01-01 00:00:00.000000000 +0000 ++++ linux/drivers/input/joystick/xu10-joypad.c 2024-01-29 06:19:30.953540557 +0000 @@ -0,0 +1,1119 @@ +/* + * SARADC joystick & GPIO Button driver for Linux(Hardkernel MagicX-XU10) @@ -4470,8 +5854,8 @@ diff -rupN linux.orig/drivers/input/joystick/odroidgo3-joypad.c linux/drivers/in + +/*----------------------------------------------------------------------------*/ diff -rupN linux.orig/drivers/power/supply/rk817_charger.c linux/drivers/power/supply/rk817_charger.c ---- linux.orig/drivers/power/supply/rk817_charger.c 2024-01-17 03:47:12.974420120 +0000 -+++ linux/drivers/power/supply/rk817_charger.c 2024-01-17 04:04:33.550547556 +0000 +--- linux.orig/drivers/power/supply/rk817_charger.c 2024-01-29 06:18:08.779726126 +0000 ++++ linux/drivers/power/supply/rk817_charger.c 2024-01-29 06:19:30.953540557 +0000 @@ -679,7 +679,7 @@ static enum power_supply_usb_type rk817_ }; @@ -4483,7 +5867,7 @@ diff -rupN linux.orig/drivers/power/supply/rk817_charger.c linux/drivers/power/s .num_properties = ARRAY_SIZE(rk817_bat_props), diff -rupN linux.orig/include/linux/input-polldev.h linux/include/linux/input-polldev.h --- linux.orig/include/linux/input-polldev.h 1970-01-01 00:00:00.000000000 +0000 -+++ linux/include/linux/input-polldev.h 2024-01-17 04:04:33.550547556 +0000 ++++ linux/include/linux/input-polldev.h 2024-01-29 06:19:30.953540557 +0000 @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _INPUT_POLLDEV_H @@ -4544,8 +5928,8 @@ diff -rupN linux.orig/include/linux/input-polldev.h linux/include/linux/input-po + +#endif diff -rupN linux.orig/include/linux/of_gpio.h linux/include/linux/of_gpio.h ---- linux.orig/include/linux/of_gpio.h 2024-01-17 03:47:13.794439908 +0000 -+++ linux/include/linux/of_gpio.h 2024-01-17 04:04:33.550547556 +0000 +--- linux.orig/include/linux/of_gpio.h 2024-01-29 06:18:09.007731389 +0000 ++++ linux/include/linux/of_gpio.h 2024-01-29 06:19:30.953540557 +0000 @@ -17,8 +17,26 @@ struct device_node; diff --git a/projects/Rockchip/packages/linux/patches/RK3326/005-unigue-gpio-guid.patch b/projects/Rockchip/packages/linux/patches/RK3326/005-unigue-gpio-guid.patch new file mode 100644 index 0000000000..92cce0e352 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RK3326/005-unigue-gpio-guid.patch @@ -0,0 +1,14 @@ +diff -rupN linux.orig/drivers/input/keyboard/gpio_keys.c linux/drivers/input/keyboard/gpio_keys.c +--- linux.orig/drivers/input/keyboard/gpio_keys.c 2024-01-25 20:47:47.094097973 +0000 ++++ linux/drivers/input/keyboard/gpio_keys.c 2024-01-26 04:17:54.663672057 +0000 +@@ -847,8 +847,8 @@ static int gpio_keys_probe(struct platfo + + input->id.bustype = BUS_HOST; + input->id.vendor = 0x0001; +- input->id.product = 0x0001; +- input->id.version = 0x0100; ++ input->id.product = 0x7891; ++ input->id.version = 0x0500; + + input->keycode = ddata->keymap; + input->keycodesize = sizeof(ddata->keymap[0]); diff --git a/projects/Rockchip/packages/linux/patches/RK3326/100-panfrost-memory-shrinker.patch b/projects/Rockchip/packages/linux/patches/RK3326/100-panfrost-memory-shrinker.patch new file mode 100644 index 0000000000..eab5999678 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RK3326/100-panfrost-memory-shrinker.patch @@ -0,0 +1,5235 @@ +* [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers +@ 2024-01-05 18:45 Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko + ` (29 more replies) + 0 siblings, 30 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +This series: + + 1. Adds common drm-shmem memory shrinker + 2. Moves drm-shmem drivers to new SGT usage policy + 3. Enables shrinker for VirtIO-GPU driver + 4. Switches Panfrost driver to the common shrinker + 5. Fixes bugs and improves/refactors drm-shmem code + +Mesa: https://gitlab.freedesktop.org/digetx/mesa/-/commits/virgl-madvise +IGT: https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/virtio-madvise + https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/panfrost-madvise + +Changelog: + +v19:- Addressed v18 review comments from Boris Brezillon: + + - Improved bisectablity of Panfrost and drm-shmem patches by + fixing iterim warning splats related to shrinker changes. + + - Improved commit messages + + - Reworked Lima patch to avoid adding `put_pages` flag + + - Reworked Panfrost patch that switches driver to explicit + get/put pages by moving drm_gem_shmem_put_pages() into + gem_mapping_release() instead of gem_free_object(). + + - Updated Panfrost patch that switches driver to generic shrinker + with more comments and minor imporovemnts. + + - Added new Panfrost patch from Boris that fixes handling of + a partially mapped heap BOs. + + - Added link to the related Mesa MR to the commit msg of the patch + that adds new DRM_VIRTGPU_MADVISE ioctl, like was requested by + Gurchetan Singh. + + - Added ackes/r-b from Boris Brezillon and Maxime Ripard + + - New patches in v19: + + drm/gem: Document locking rule of vmap and evict callbacks + drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + + - Factored out couple code changes into these new separate patches: + + drm/shmem-helper: Avoid lockdep warning when pages are released + drm/shmem-helper: Turn warnings about imported GEM into errors + +v18:- Added new pathes that change sgt allocation policy. Previously once + sgt was allocated, it exsited till GEM was freed. Now sgt is destroyed + once pages are unpinned and drivers have to manage the pages' pinning + refcounting by themselves using get/put() and pin/unpin() pages. + This removes pages refcounting ambiguity from the drm-shmem core. + + - Dropped patch that changed drm_gem_shmem_vmap_locked() error handling, + like was requested by Boris Brezillon. + + - Added new patches that make minor improvements: + + - Optimize unlocked get_pages_sgt() + - Don't free refcounted GEM + + - Dropped t-b from the Panfrost shrinker patch that was given for older + patch version since code changed with the new sgt allocation policy. + +v17:- Dropped patches that added new drm-shmem sgt flags, fixing dma-buf UAF + in drm-prime error code path and preventing invalid page_count when GEM + is freed. Will revist them later on and then factor them out into a + seprate patchset. + + - Dropped patches that replaced drm_gem_shmem_free() with + drm_gem_object_put(), they not needed anymore after changing + drm_gem_shmem_free() to not touch reservation lock. + + - Addressed review comments from Boris Brezillon: + + - Added new patch to clean up error unwinding in + drm_gem_shmem_vmap_locked() + + - Added new __drm_gem_shmem_put_pages() to let the callers + to assert the held reservation lock themselves + + - Moved replacement of shmem->pages check with refcount_read() + in drm_gem_shmem_free() to the shrinker addition patch + + - Improved commit message of the vmap_use_count patch + + - Added r-bs from Boris Brezillon that he gave to v16 + +v16:- Added more comments to the code for the new drm-shmem flags + + - Added r-bs from Boris Brezillon + + - Fixed typos and made impovements pointed out by Boris Brezillon + + - Replaced kref with refcount_t as was suggested by Boris Brezillon + + - Corrected placement of got_sgt flag in the Lima driver, also renamed + flag to got_pages_sgt + + - Removed drm_gem_shmem_resv_assert_held() and made drm_gem_shmem_free() + to free pages without a new func that doesn't touch resv lock, as was + suggested by Boris Brezillon + + - Added pages_pin_count to drm_gem_shmem_print_info() + +v15:- Moved drm-shmem reference counters to use kref that allows to + optimize unlocked functions, like was suggested by Boris Brezillon. + + - Changed drm/gem/shmem function names to use _locked postfix and + dropped the _unlocked, making the naming scheme consistent across + DRM code, like was suggested by Boris Brezillon. + + - Added patch that fixes UAF in drm-shmem for drivers that import + dma-buf and then release buffer in the import error code path. + + - Added patch that makes drm-shmem use new flag for SGT's get_pages() + refcounting, preventing unbalanced refcounting when GEM is freed. + + - Fixed guest blob pinning in virtio-gpu driver that was missed + previously in the shrinker patch. + + - Moved VC4 and virtio-gpu drivers to use drm_gem_put() in + GEM-creation error code paths, which is now required by drm-shmem + and was missed in a previous patch versions. + + - Virtio-GPU now attaches shmem pages to host on first use and not + when BO is created. In older patch versions there was a potential + race condition in the BO creation code path where both + get_sgt()+object_attach() should've been made under same resv lock, + otherwise pages could be evicted before attachment is invoked. + + - Virtio-GPU and drm-shmem shrinker patches are split into smaller + ones. + +v14:- All the prerequisite reservation locking patches landed upstream, + previously were a part of this series in v13 and older. + + https://lore.kernel.org/dri-devel/20230529223935.2672495-1-dmitry.osipenko@collabora.com/ + + - Added patches to improve locked/unlocked function names, like was + suggested by Boris Brezillon for v13. + + - Made all exported drm-shmem symbols GPL, like was previously + discussed with Thomas Zimmermann on this series. + + - Improved virtio-gpu shrinker patch. Now it won't detach purged BO + when userspace closes GEM. Crosvm (and not qemu) checks res_id on + CMD_CTX_DETACH_RESOURCE and prints noisy error message if ID is + invalid, which wasn't noticed before. + +v13:- Updated virtio-gpu shrinker patch to use drm_gem_shmem_object_pin() + directly instead of drm_gem_pin() and dropped patch that exported + drm_gem_pin() functions, like was requested by Thomas Zimmermann in + v12. + +v12:- Fixed the "no previous prototype for function" warning reported by + kernel build bot for v11. + + - Fixed the missing reservation lock reported by Intel CI for VGEM + driver. Other drivers using drm-shmem were affected similarly to + VGEM. The problem was in the dma-buf attachment code path that led + to drm-shmem pinning function which assumed the held reservation lock + by drm_gem_pin(). In the past that code path was causing trouble for + i915 driver and we've changed the locking scheme for the attachment + code path in the dma-buf core to let exporters to handle the locking + themselves. After a closer investigation, I realized that my assumption + about testing of dma-buf export code path using Panfrost driver was + incorrect. Now I created additional local test to exrecise the Panfrost + export path. I also reproduced the issue reported by the Intel CI for + v10. It's all fixed now by making the drm_gem_shmem_pin() to take the + resv lock by itself. + + - Patches are based on top of drm-tip, CC'd intel-gfx CI for testing. + +v11:- Rebased on a recent linux-next. Added new patch as a result: + + drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() + + It's needed by the virtio-gpu driver to swap-in/unevict shmem + object, previously get_pages_sgt() didn't use locking. + + - Separated the "Add memory shrinker" patch into smaller parts to ease + the reviewing, as was requested by Thomas Zimmermann: + + drm/shmem-helper: Factor out pages alloc/release from + drm_gem_shmem_get/put_pages() + drm/shmem-helper: Add pages_pin_count field + drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin + drm/shmem-helper: Factor out unpinning part from drm_gem_shmem_purge() + + - Addessed the v10 review comments from Thomas Zimmermann: return errno + instead of bool, sort code alphabetically, rename function and etc + minor changes. + + - Added new patch to remove the "map->is_iomem" from drm-shmem, as + was suggested by Thomas Zimmermann. + + - Added acks and r-b's that were given to v10. + +v10:- Was partially applied to misc-fixes/next. + + https://lore.kernel.org/dri-devel/6c16f303-81df-7ebe-85e9-51bb40a8b301@collabora.com/T/ + +Boris Brezillon (1): + drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + +Dmitry Osipenko (29): + drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function + names + drm/gem: Add _locked postfix to functions that have unlocked + counterpart + drm/gem: Document locking rule of vmap and evict callbacks + drm/shmem-helper: Make all exported symbols GPL + drm/shmem-helper: Refactor locked/unlocked functions + drm/shmem-helper: Remove obsoleted is_iomem test + drm/shmem-helper: Add and use pages_pin_count + drm/shmem-helper: Use refcount_t for pages_use_count + drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() + drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin + drm/shmem-helper: Use refcount_t for vmap_use_count + drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition + drm/shmem-helper: Make drm_gem_shmem_get_pages() public + drm/shmem-helper: Add drm_gem_shmem_put_pages() + drm/shmem-helper: Avoid lockdep warning when pages are released + drm/lima: Explicitly get and put drm-shmem pages + drm/panfrost: Explicitly get and put drm-shmem pages + drm/virtio: Explicitly get and put drm-shmem pages + drm/v3d: Explicitly get and put drm-shmem pages + drm/shmem-helper: Change sgt allocation policy + drm/shmem-helper: Add common memory shrinker + drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() + drm/shmem-helper: Optimize unlocked get_pages_sgt() + drm/shmem-helper: Don't free refcounted GEM + drm/shmem-helper: Turn warnings about imported GEM into errors + drm/virtio: Pin display framebuffer BO + drm/virtio: Attach shmem BOs dynamically + drm/virtio: Support shmem shrinking + drm/panfrost: Switch to generic memory shrinker + + drivers/gpu/drm/drm_client.c | 6 +- + drivers/gpu/drm/drm_gem.c | 26 +- + drivers/gpu/drm/drm_gem_framebuffer_helper.c | 6 +- + drivers/gpu/drm/drm_gem_shmem_helper.c | 663 +++++++++++++++--- + drivers/gpu/drm/drm_internal.h | 4 +- + drivers/gpu/drm/drm_prime.c | 4 +- + drivers/gpu/drm/lima/lima_gem.c | 23 +- + drivers/gpu/drm/lima/lima_sched.c | 4 +- + drivers/gpu/drm/panfrost/Makefile | 1 - + drivers/gpu/drm/panfrost/panfrost_device.h | 4 - + drivers/gpu/drm/panfrost/panfrost_drv.c | 31 +- + drivers/gpu/drm/panfrost/panfrost_dump.c | 4 +- + drivers/gpu/drm/panfrost/panfrost_gem.c | 110 ++- + drivers/gpu/drm/panfrost/panfrost_gem.h | 9 - + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 127 ---- + drivers/gpu/drm/panfrost/panfrost_job.c | 18 +- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 39 +- + drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 6 +- + drivers/gpu/drm/v3d/v3d_bo.c | 11 +- + drivers/gpu/drm/virtio/virtgpu_drv.h | 22 +- + drivers/gpu/drm/virtio/virtgpu_gem.c | 85 +++ + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 57 +- + drivers/gpu/drm/virtio/virtgpu_kms.c | 8 + + drivers/gpu/drm/virtio/virtgpu_object.c | 143 +++- + drivers/gpu/drm/virtio/virtgpu_plane.c | 17 +- + drivers/gpu/drm/virtio/virtgpu_submit.c | 15 +- + drivers/gpu/drm/virtio/virtgpu_vq.c | 40 ++ + include/drm/drm_device.h | 10 +- + include/drm/drm_gem.h | 15 +- + include/drm/drm_gem_shmem_helper.h | 117 +++- + include/uapi/drm/virtgpu_drm.h | 14 + + 31 files changed, 1216 insertions(+), 423 deletions(-) + delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c + +-- +2.43.0 + + +^ permalink raw reply [flat|nested] 31+ messages in thread +* [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart Dmitry Osipenko + ` (28 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Make drm/gem API function names consistent by having locked function +use the _locked postfix in the name, while the unlocked variants don't +use the _unlocked postfix. Rename drm_gem_v/unmap() function names to +make them consistent with the rest of the API functions. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_client.c | 6 +++--- + drivers/gpu/drm/drm_gem.c | 20 ++++++++++---------- + drivers/gpu/drm/drm_gem_framebuffer_helper.c | 6 +++--- + drivers/gpu/drm/drm_internal.h | 4 ++-- + drivers/gpu/drm/drm_prime.c | 4 ++-- + drivers/gpu/drm/lima/lima_sched.c | 4 ++-- + drivers/gpu/drm/panfrost/panfrost_dump.c | 4 ++-- + drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 6 +++--- + include/drm/drm_gem.h | 4 ++-- + 9 files changed, 29 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c +index 9403b3f576f7..7ee9baf46eaa 100644 +--- a/drivers/gpu/drm/drm_client.c ++++ b/drivers/gpu/drm/drm_client.c +@@ -255,7 +255,7 @@ void drm_client_dev_restore(struct drm_device *dev) + static void drm_client_buffer_delete(struct drm_client_buffer *buffer) + { + if (buffer->gem) { +- drm_gem_vunmap_unlocked(buffer->gem, &buffer->map); ++ drm_gem_vunmap(buffer->gem, &buffer->map); + drm_gem_object_put(buffer->gem); + } + +@@ -339,7 +339,7 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer, + * fd_install step out of the driver backend hooks, to make that + * final step optional for internal users. + */ +- ret = drm_gem_vmap_unlocked(buffer->gem, map); ++ ret = drm_gem_vmap(buffer->gem, map); + if (ret) + return ret; + +@@ -361,7 +361,7 @@ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer) + { + struct iosys_map *map = &buffer->map; + +- drm_gem_vunmap_unlocked(buffer->gem, map); ++ drm_gem_vunmap(buffer->gem, map); + } + EXPORT_SYMBOL(drm_client_buffer_vunmap); + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 44a948b80ee1..95327b003692 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -1175,7 +1175,7 @@ void drm_gem_unpin(struct drm_gem_object *obj) + obj->funcs->unpin(obj); + } + +-int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) ++int drm_gem_vmap_locked(struct drm_gem_object *obj, struct iosys_map *map) + { + int ret; + +@@ -1192,9 +1192,9 @@ int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) + + return 0; + } +-EXPORT_SYMBOL(drm_gem_vmap); ++EXPORT_SYMBOL(drm_gem_vmap_locked); + +-void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) ++void drm_gem_vunmap_locked(struct drm_gem_object *obj, struct iosys_map *map) + { + dma_resv_assert_held(obj->resv); + +@@ -1207,27 +1207,27 @@ void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) + /* Always set the mapping to NULL. Callers may rely on this. */ + iosys_map_clear(map); + } +-EXPORT_SYMBOL(drm_gem_vunmap); ++EXPORT_SYMBOL(drm_gem_vunmap_locked); + +-int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map) ++int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) + { + int ret; + + dma_resv_lock(obj->resv, NULL); +- ret = drm_gem_vmap(obj, map); ++ ret = drm_gem_vmap_locked(obj, map); + dma_resv_unlock(obj->resv); + + return ret; + } +-EXPORT_SYMBOL(drm_gem_vmap_unlocked); ++EXPORT_SYMBOL(drm_gem_vmap); + +-void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map) ++void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) + { + dma_resv_lock(obj->resv, NULL); +- drm_gem_vunmap(obj, map); ++ drm_gem_vunmap_locked(obj, map); + dma_resv_unlock(obj->resv); + } +-EXPORT_SYMBOL(drm_gem_vunmap_unlocked); ++EXPORT_SYMBOL(drm_gem_vunmap); + + /** + * drm_gem_lock_reservations - Sets up the ww context and acquires +diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c +index 3bdb6ba37ff4..3808f47310bf 100644 +--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c ++++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c +@@ -362,7 +362,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, + ret = -EINVAL; + goto err_drm_gem_vunmap; + } +- ret = drm_gem_vmap_unlocked(obj, &map[i]); ++ ret = drm_gem_vmap(obj, &map[i]); + if (ret) + goto err_drm_gem_vunmap; + } +@@ -384,7 +384,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, + obj = drm_gem_fb_get_obj(fb, i); + if (!obj) + continue; +- drm_gem_vunmap_unlocked(obj, &map[i]); ++ drm_gem_vunmap(obj, &map[i]); + } + return ret; + } +@@ -411,7 +411,7 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map) + continue; + if (iosys_map_is_null(&map[i])) + continue; +- drm_gem_vunmap_unlocked(obj, &map[i]); ++ drm_gem_vunmap(obj, &map[i]); + } + } + EXPORT_SYMBOL(drm_gem_fb_vunmap); +diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h +index 8e4faf0a28e6..227f58e5b232 100644 +--- a/drivers/gpu/drm/drm_internal.h ++++ b/drivers/gpu/drm/drm_internal.h +@@ -172,8 +172,8 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, + + int drm_gem_pin(struct drm_gem_object *obj); + void drm_gem_unpin(struct drm_gem_object *obj); +-int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map); +-void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map); ++int drm_gem_vmap_locked(struct drm_gem_object *obj, struct iosys_map *map); ++void drm_gem_vunmap_locked(struct drm_gem_object *obj, struct iosys_map *map); + + /* drm_debugfs.c drm_debugfs_crc.c */ + #if defined(CONFIG_DEBUG_FS) +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 834a5e28abbe..4a5935a400ec 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -684,7 +684,7 @@ int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct iosys_map *map) + { + struct drm_gem_object *obj = dma_buf->priv; + +- return drm_gem_vmap(obj, map); ++ return drm_gem_vmap_locked(obj, map); + } + EXPORT_SYMBOL(drm_gem_dmabuf_vmap); + +@@ -700,7 +700,7 @@ void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map) + { + struct drm_gem_object *obj = dma_buf->priv; + +- drm_gem_vunmap(obj, map); ++ drm_gem_vunmap_locked(obj, map); + } + EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); + +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index c3bf8cda8498..3813f30480ba 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -371,7 +371,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) + } else { + buffer_chunk->size = lima_bo_size(bo); + +- ret = drm_gem_vmap_unlocked(&bo->base.base, &map); ++ ret = drm_gem_vmap(&bo->base.base, &map); + if (ret) { + kvfree(et); + goto out; +@@ -379,7 +379,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) + + memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size); + +- drm_gem_vunmap_unlocked(&bo->base.base, &map); ++ drm_gem_vunmap(&bo->base.base, &map); + } + + buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size; +diff --git a/drivers/gpu/drm/panfrost/panfrost_dump.c b/drivers/gpu/drm/panfrost/panfrost_dump.c +index 47751302f1bc..4042afe2fbf4 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_dump.c ++++ b/drivers/gpu/drm/panfrost/panfrost_dump.c +@@ -209,7 +209,7 @@ void panfrost_core_dump(struct panfrost_job *job) + goto dump_header; + } + +- ret = drm_gem_vmap_unlocked(&bo->base.base, &map); ++ ret = drm_gem_vmap(&bo->base.base, &map); + if (ret) { + dev_err(pfdev->dev, "Panfrost Dump: couldn't map Buffer Object\n"); + iter.hdr->bomap.valid = 0; +@@ -228,7 +228,7 @@ void panfrost_core_dump(struct panfrost_job *job) + vaddr = map.vaddr; + memcpy(iter.data, vaddr, bo->base.base.size); + +- drm_gem_vunmap_unlocked(&bo->base.base, &map); ++ drm_gem_vunmap(&bo->base.base, &map); + + iter.hdr->bomap.valid = 1; + +diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +index ba9b6e2b2636..52befead08c6 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c ++++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +@@ -106,7 +106,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, + goto err_close_bo; + } + +- ret = drm_gem_vmap_unlocked(&bo->base, &map); ++ ret = drm_gem_vmap(&bo->base, &map); + if (ret) + goto err_put_mapping; + perfcnt->buf = map.vaddr; +@@ -165,7 +165,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, + return 0; + + err_vunmap: +- drm_gem_vunmap_unlocked(&bo->base, &map); ++ drm_gem_vunmap(&bo->base, &map); + err_put_mapping: + panfrost_gem_mapping_put(perfcnt->mapping); + err_close_bo: +@@ -195,7 +195,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, + GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_OFF)); + + perfcnt->user = NULL; +- drm_gem_vunmap_unlocked(&perfcnt->mapping->obj->base.base, &map); ++ drm_gem_vunmap(&perfcnt->mapping->obj->base.base, &map); + perfcnt->buf = NULL; + panfrost_gem_close(&perfcnt->mapping->obj->base.base, file_priv); + panfrost_mmu_as_put(pfdev, perfcnt->mapping->mmu); +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index 369505447acd..decb19ffb2c8 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -527,8 +527,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj); + void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, + bool dirty, bool accessed); + +-int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map); +-void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map); ++int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map); ++void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map); + + int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles, + int count, struct drm_gem_object ***objs_out); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks Dmitry Osipenko + ` (27 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add _locked postfix to drm_gem functions that have unlocked counterpart +functions to make GEM functions naming more consistent and intuitive in +regards to the locking requirements. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem.c | 6 +++--- + include/drm/drm_gem.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 95327b003692..4523cd40fb2f 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -1490,10 +1490,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru, + EXPORT_SYMBOL(drm_gem_lru_scan); + + /** +- * drm_gem_evict - helper to evict backing pages for a GEM object ++ * drm_gem_evict_locked - helper to evict backing pages for a GEM object + * @obj: obj in question + */ +-int drm_gem_evict(struct drm_gem_object *obj) ++int drm_gem_evict_locked(struct drm_gem_object *obj) + { + dma_resv_assert_held(obj->resv); + +@@ -1505,4 +1505,4 @@ int drm_gem_evict(struct drm_gem_object *obj) + + return 0; + } +-EXPORT_SYMBOL(drm_gem_evict); ++EXPORT_SYMBOL(drm_gem_evict_locked); +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index decb19ffb2c8..f835fdee6a5e 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -551,7 +551,7 @@ unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, + unsigned long *remaining, + bool (*shrink)(struct drm_gem_object *obj)); + +-int drm_gem_evict(struct drm_gem_object *obj); ++int drm_gem_evict_locked(struct drm_gem_object *obj); + + #ifdef CONFIG_LOCKDEP + /** +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL Dmitry Osipenko + ` (26 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +The vmap/vunmap/evict GEM callbacks are always invoked with a held GEM's +reservation lock. Document this locking rule for clarity. + +Signed-off-by: Dmitry Osipenko +--- + include/drm/drm_gem.h | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index f835fdee6a5e..021f64371056 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -156,7 +156,8 @@ struct drm_gem_object_funcs { + * @vmap: + * + * Returns a virtual address for the buffer. Used by the +- * drm_gem_dmabuf_vmap() helper. ++ * drm_gem_dmabuf_vmap() helper. Called with a held GEM reservation ++ * lock. + * + * This callback is optional. + */ +@@ -166,7 +167,8 @@ struct drm_gem_object_funcs { + * @vunmap: + * + * Releases the address previously returned by @vmap. Used by the +- * drm_gem_dmabuf_vunmap() helper. ++ * drm_gem_dmabuf_vunmap() helper. Called with a held GEM reservation ++ * lock. + * + * This callback is optional. + */ +@@ -189,7 +191,8 @@ struct drm_gem_object_funcs { + * @evict: + * + * Evicts gem object out from memory. Used by the drm_gem_object_evict() +- * helper. Returns 0 on success, -errno otherwise. ++ * helper. Returns 0 on success, -errno otherwise. Called with a held ++ * GEM reservation lock. + * + * This callback is optional. + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (2 preceding siblings ...) + 2024-01-05 18:45 ` [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions Dmitry Osipenko + ` (25 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Make all drm-shmem exported symbols GPL to make them consistent with +the rest of drm-shmem symbols. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index e435f986cd13..0d61f2b3e213 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -226,7 +226,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) + shmem->pages_mark_accessed_on_put); + shmem->pages = NULL; + } +-EXPORT_SYMBOL(drm_gem_shmem_put_pages); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); + + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { +@@ -271,7 +271,7 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) + + return ret; + } +-EXPORT_SYMBOL(drm_gem_shmem_pin); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_pin); + + /** + * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object +@@ -290,7 +290,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + drm_gem_shmem_unpin_locked(shmem); + dma_resv_unlock(shmem->base.resv); + } +-EXPORT_SYMBOL(drm_gem_shmem_unpin); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); + + /* + * drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object +@@ -360,7 +360,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + + return ret; + } +-EXPORT_SYMBOL(drm_gem_shmem_vmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap); + + /* + * drm_gem_shmem_vunmap - Unmap a virtual mapping for a shmem GEM object +@@ -396,7 +396,7 @@ void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, + + shmem->vaddr = NULL; + } +-EXPORT_SYMBOL(drm_gem_shmem_vunmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap); + + static int + drm_gem_shmem_create_with_handle(struct drm_file *file_priv, +@@ -435,7 +435,7 @@ int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) + + return (madv >= 0); + } +-EXPORT_SYMBOL(drm_gem_shmem_madvise); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise); + + void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + { +@@ -467,7 +467,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + + invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); + } +-EXPORT_SYMBOL(drm_gem_shmem_purge); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_purge); + + /** + * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object +@@ -642,7 +642,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); + } +-EXPORT_SYMBOL(drm_gem_shmem_print_info); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); + + /** + * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (3 preceding siblings ...) + 2024-01-05 18:45 ` [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test Dmitry Osipenko + ` (24 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add locked and remove unlocked postfixes from drm-shmem function names, +making names consistent with the drm/gem core code. + +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 60 +++++++++---------- + drivers/gpu/drm/lima/lima_gem.c | 6 +- + drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- + drivers/gpu/drm/panfrost/panfrost_gem.c | 2 +- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- + include/drm/drm_gem_shmem_helper.h | 28 ++++----- + 7 files changed, 51 insertions(+), 51 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 0d61f2b3e213..043e8e3b129c 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -153,7 +153,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + kfree(shmem->sgt); + } + if (shmem->pages) +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + + drm_WARN_ON(obj->dev, shmem->pages_use_count); + +@@ -165,7 +165,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_free); + +-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) ++static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + struct page **pages; +@@ -199,12 +199,12 @@ static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + } + + /* +- * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a shmem GEM object ++ * drm_gem_shmem_put_pages_locked - Decrease use count on the backing pages for a shmem GEM object + * @shmem: shmem GEM object + * + * This function decreases the use count and puts the backing pages when use drops to zero. + */ +-void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) ++void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + +@@ -226,7 +226,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) + shmem->pages_mark_accessed_on_put); + shmem->pages = NULL; + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { +@@ -234,7 +234,7 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + + return ret; + } +@@ -243,7 +243,7 @@ static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) + { + dma_resv_assert_held(shmem->base.resv); + +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + } + + /** +@@ -293,7 +293,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); + + /* +- * drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object ++ * drm_gem_shmem_vmap_locked - Create a virtual mapping for a shmem GEM object + * @shmem: shmem GEM object + * @map: Returns the kernel virtual address of the SHMEM GEM object's backing + * store. +@@ -302,13 +302,13 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); + * exists for the buffer backing the shmem GEM object. It hides the differences + * between dma-buf imported and natively allocated objects. + * +- * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap(). ++ * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap_locked(). + * + * Returns: + * 0 on success or a negative error code on failure. + */ +-int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map) ++int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map) + { + struct drm_gem_object *obj = &shmem->base; + int ret = 0; +@@ -331,7 +331,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + return 0; + } + +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + if (ret) + goto err_zero_use; + +@@ -354,28 +354,28 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + + err_put_pages: + if (!obj->import_attach) +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + err_zero_use: + shmem->vmap_use_count = 0; + + return ret; + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap_locked); + + /* +- * drm_gem_shmem_vunmap - Unmap a virtual mapping for a shmem GEM object ++ * drm_gem_shmem_vunmap_locked - Unmap a virtual mapping for a shmem GEM object + * @shmem: shmem GEM object + * @map: Kernel virtual address where the SHMEM GEM object was mapped + * + * This function cleans up a kernel virtual address mapping acquired by +- * drm_gem_shmem_vmap(). The mapping is only removed when the use count drops to +- * zero. ++ * drm_gem_shmem_vmap_locked(). The mapping is only removed when the use count ++ * drops to zero. + * + * This function hides the differences between dma-buf imported and natively + * allocated objects. + */ +-void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map) ++void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map) + { + struct drm_gem_object *obj = &shmem->base; + +@@ -391,12 +391,12 @@ void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, + return; + + vunmap(shmem->vaddr); +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + } + + shmem->vaddr = NULL; + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap_locked); + + static int + drm_gem_shmem_create_with_handle(struct drm_file *file_priv, +@@ -424,7 +424,7 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv, + /* Update madvise status, returns true if not purged, else + * false or -errno. + */ +-int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) ++int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv) + { + dma_resv_assert_held(shmem->base.resv); + +@@ -435,9 +435,9 @@ int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) + + return (madv >= 0); + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked); + +-void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) ++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + struct drm_device *dev = obj->dev; +@@ -451,7 +451,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + kfree(shmem->sgt); + shmem->sgt = NULL; + +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + + shmem->madv = -1; + +@@ -467,7 +467,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + + invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_purge); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked); + + /** + * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object +@@ -564,7 +564,7 @@ static void drm_gem_shmem_vm_close(struct vm_area_struct *vma) + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + + dma_resv_lock(shmem->base.resv, NULL); +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + dma_resv_unlock(shmem->base.resv); + + drm_gem_vm_close(vma); +@@ -611,7 +611,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct + } + + dma_resv_lock(shmem->base.resv, NULL); +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + dma_resv_unlock(shmem->base.resv); + + if (ret) +@@ -679,7 +679,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + + drm_WARN_ON(obj->dev, obj->import_attach); + +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + if (ret) + return ERR_PTR(ret); + +@@ -701,7 +701,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + sg_free_table(sgt); + kfree(sgt); + err_put_pages: +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + return ERR_PTR(ret); + } + +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index 4f9736e5f929..433bda72e59b 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -180,7 +180,7 @@ static int lima_gem_pin(struct drm_gem_object *obj) + if (bo->heap_size) + return -EINVAL; + +- return drm_gem_shmem_pin(&bo->base); ++ return drm_gem_shmem_object_pin(obj); + } + + static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) +@@ -190,7 +190,7 @@ static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) + if (bo->heap_size) + return -EINVAL; + +- return drm_gem_shmem_vmap(&bo->base, map); ++ return drm_gem_shmem_object_vmap(obj, map); + } + + static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +@@ -200,7 +200,7 @@ static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) + if (bo->heap_size) + return -EINVAL; + +- return drm_gem_shmem_mmap(&bo->base, vma); ++ return drm_gem_shmem_object_mmap(obj, vma); + } + + static const struct drm_gem_object_funcs lima_gem_funcs = { +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index a926d71e8131..a15d62f19afb 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -438,7 +438,7 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + } + } + +- args->retained = drm_gem_shmem_madvise(&bo->base, args->madv); ++ args->retained = drm_gem_shmem_madvise_locked(&bo->base, args->madv); + + if (args->retained) { + if (args->madv == PANFROST_MADV_DONTNEED) +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index d47b40b82b0b..f268bd5c2884 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -192,7 +192,7 @@ static int panfrost_gem_pin(struct drm_gem_object *obj) + if (bo->is_heap) + return -EINVAL; + +- return drm_gem_shmem_pin(&bo->base); ++ return drm_gem_shmem_object_pin(obj); + } + + static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object *obj) +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +index 3d9f51bd48b6..02b60ea1433a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +@@ -51,7 +51,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) + goto unlock_mappings; + + panfrost_gem_teardown_mappings_locked(bo); +- drm_gem_shmem_purge(&bo->base); ++ drm_gem_shmem_purge_locked(&bo->base); + ret = true; + + dma_resv_unlock(shmem->base.resv); +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index f38385fe76bb..1ab081bd81a8 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -538,7 +538,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + err_map: + sg_free_table(sgt); + err_pages: +- drm_gem_shmem_put_pages(&bo->base); ++ drm_gem_shmem_put_pages_locked(&bo->base); + err_unlock: + dma_resv_unlock(obj->resv); + err_bo: +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index bf0c31aa8fbe..9e83212becbb 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -99,16 +99,16 @@ struct drm_gem_shmem_object { + struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size); + void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); + +-void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); ++void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); + int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem); +-int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map); +-void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map); ++int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map); ++void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map); + int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma); + +-int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv); ++int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv); + + static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) + { +@@ -117,7 +117,7 @@ static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem + !shmem->base.dma_buf && !shmem->base.import_attach; + } + +-void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem); ++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem); + + struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem); + struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem); +@@ -208,12 +208,12 @@ static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_ + } + + /* +- * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap() ++ * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap_locked() + * @obj: GEM object + * @map: Returns the kernel virtual address of the SHMEM GEM object's backing store. + * +- * This function wraps drm_gem_shmem_vmap(). Drivers that employ the shmem helpers should +- * use it as their &drm_gem_object_funcs.vmap handler. ++ * This function wraps drm_gem_shmem_vmap_locked(). Drivers that employ the shmem ++ * helpers should use it as their &drm_gem_object_funcs.vmap handler. + * + * Returns: + * 0 on success or a negative error code on failure. +@@ -223,7 +223,7 @@ static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, + { + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + +- return drm_gem_shmem_vmap(shmem, map); ++ return drm_gem_shmem_vmap_locked(shmem, map); + } + + /* +@@ -231,15 +231,15 @@ static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, + * @obj: GEM object + * @map: Kernel virtual address where the SHMEM GEM object was mapped + * +- * This function wraps drm_gem_shmem_vunmap(). Drivers that employ the shmem helpers should +- * use it as their &drm_gem_object_funcs.vunmap handler. ++ * This function wraps drm_gem_shmem_vunmap_locked(). Drivers that employ the shmem ++ * helpers should use it as their &drm_gem_object_funcs.vunmap handler. + */ + static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, + struct iosys_map *map) + { + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + +- drm_gem_shmem_vunmap(shmem, map); ++ drm_gem_shmem_vunmap_locked(shmem, map); + } + + /** +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (4 preceding siblings ...) + 2024-01-05 18:45 ` [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count Dmitry Osipenko + ` (23 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Everything that uses the mapped buffer should be agnostic to is_iomem. +The only reason for the is_iomem test is that we're setting shmem->vaddr +to the returned map->vaddr. Now that the shmem->vaddr code is gone, remove +the obsoleted is_iomem test to clean up the code. + +Acked-by: Maxime Ripard +Suggested-by: Thomas Zimmermann +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 043e8e3b129c..1f0a66386415 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -315,12 +315,6 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + + if (obj->import_attach) { + ret = dma_buf_vmap(obj->import_attach->dmabuf, map); +- if (!ret) { +- if (drm_WARN_ON(obj->dev, map->is_iomem)) { +- dma_buf_vunmap(obj->import_attach->dmabuf, map); +- return -EIO; +- } +- } + } else { + pgprot_t prot = PAGE_KERNEL; + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (5 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count Dmitry Osipenko + ` (22 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add separate pages_pin_count for tracking of whether drm-shmem pages are +moveable or not. With the addition of memory shrinker support to drm-shmem, +the pages_use_count will no longer determine whether pages are hard-pinned +in memory, but whether pages exist and are soft-pinned (and could be swapped +out). The pages_pin_count > 1 will hard-pin pages in memory. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 25 +++++++++++++++++-------- + include/drm/drm_gem_shmem_helper.h | 11 +++++++++++ + 2 files changed, 28 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 1f0a66386415..55b9dd3d4b18 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -156,6 +156,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + drm_gem_shmem_put_pages_locked(shmem); + + drm_WARN_ON(obj->dev, shmem->pages_use_count); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); + + dma_resv_unlock(shmem->base.resv); + } +@@ -234,18 +235,16 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + ++ if (refcount_inc_not_zero(&shmem->pages_pin_count)) ++ return 0; ++ + ret = drm_gem_shmem_get_pages_locked(shmem); ++ if (!ret) ++ refcount_set(&shmem->pages_pin_count, 1); + + return ret; + } + +-static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) +-{ +- dma_resv_assert_held(shmem->base.resv); +- +- drm_gem_shmem_put_pages_locked(shmem); +-} +- + /** + * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object + * @shmem: shmem GEM object +@@ -263,6 +262,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) + + drm_WARN_ON(obj->dev, obj->import_attach); + ++ if (refcount_inc_not_zero(&shmem->pages_pin_count)) ++ return 0; ++ + ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); + if (ret) + return ret; +@@ -286,8 +288,14 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + + drm_WARN_ON(obj->dev, obj->import_attach); + ++ if (refcount_dec_not_one(&shmem->pages_pin_count)) ++ return; ++ + dma_resv_lock(shmem->base.resv, NULL); +- drm_gem_shmem_unpin_locked(shmem); ++ ++ if (refcount_dec_and_test(&shmem->pages_pin_count)) ++ drm_gem_shmem_put_pages_locked(shmem); ++ + dma_resv_unlock(shmem->base.resv); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); +@@ -632,6 +640,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + if (shmem->base.import_attach) + return; + ++ drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); + drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count); + drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 9e83212becbb..c708a9f45cbd 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -39,6 +39,17 @@ struct drm_gem_shmem_object { + */ + unsigned int pages_use_count; + ++ /** ++ * @pages_pin_count: ++ * ++ * Reference count on the pinned pages table. ++ * ++ * Pages are hard-pinned and reside in memory if count ++ * greater than zero. Otherwise, when count is zero, the pages are ++ * allowed to be evicted and purged by memory shrinker. ++ */ ++ refcount_t pages_pin_count; ++ + /** + * @madv: State for madvise + * +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (6 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() Dmitry Osipenko + ` (21 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Use atomic refcount_t helper for pages_use_count to optimize pin/unpin +functions by skipping reservation locking while GEM's pin refcount > 1. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 33 +++++++++++-------------- + drivers/gpu/drm/lima/lima_gem.c | 2 +- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- + include/drm/drm_gem_shmem_helper.h | 2 +- + 4 files changed, 18 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 55b9dd3d4b18..cacf0f8c42e2 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -155,7 +155,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + if (shmem->pages) + drm_gem_shmem_put_pages_locked(shmem); + +- drm_WARN_ON(obj->dev, shmem->pages_use_count); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); + + dma_resv_unlock(shmem->base.resv); +@@ -173,14 +173,13 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + +- if (shmem->pages_use_count++ > 0) ++ if (refcount_inc_not_zero(&shmem->pages_use_count)) + return 0; + + pages = drm_gem_get_pages(obj); + if (IS_ERR(pages)) { + drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n", + PTR_ERR(pages)); +- shmem->pages_use_count = 0; + return PTR_ERR(pages); + } + +@@ -196,6 +195,8 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + + shmem->pages = pages; + ++ refcount_set(&shmem->pages_use_count, 1); ++ + return 0; + } + +@@ -211,21 +212,17 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + +- if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count)) +- return; +- +- if (--shmem->pages_use_count > 0) +- return; +- ++ if (refcount_dec_and_test(&shmem->pages_use_count)) { + #ifdef CONFIG_X86 +- if (shmem->map_wc) +- set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); ++ if (shmem->map_wc) ++ set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); + #endif + +- drm_gem_put_pages(obj, shmem->pages, +- shmem->pages_mark_dirty_on_put, +- shmem->pages_mark_accessed_on_put); +- shmem->pages = NULL; ++ drm_gem_put_pages(obj, shmem->pages, ++ shmem->pages_mark_dirty_on_put, ++ shmem->pages_mark_accessed_on_put); ++ shmem->pages = NULL; ++ } + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +@@ -552,8 +549,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) + * mmap'd, vm_open() just grabs an additional reference for the new + * mm the vma is getting copied into (ie. on fork()). + */ +- if (!drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count)) +- shmem->pages_use_count++; ++ drm_WARN_ON_ONCE(obj->dev, ++ !refcount_inc_not_zero(&shmem->pages_use_count)); + + dma_resv_unlock(shmem->base.resv); + +@@ -641,7 +638,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + return; + + drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); +- drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count); ++ drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); + drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); + } +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index 433bda72e59b..2a97aa85416b 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -47,7 +47,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) + } + + bo->base.pages = pages; +- bo->base.pages_use_count = 1; ++ refcount_set(&bo->base.pages_use_count, 1); + + mapping_set_unevictable(mapping); + } +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 1ab081bd81a8..bd5a0073009d 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -489,7 +489,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + goto err_unlock; + } + bo->base.pages = pages; +- bo->base.pages_use_count = 1; ++ refcount_set(&bo->base.pages_use_count, 1); + } else { + pages = bo->base.pages; + if (pages[page_offset]) { +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index c708a9f45cbd..2c5dc62df20c 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -37,7 +37,7 @@ struct drm_gem_shmem_object { + * Reference count on the pages table. + * The pages are put when the count reaches zero. + */ +- unsigned int pages_use_count; ++ refcount_t pages_use_count; + + /** + * @pages_pin_count: +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (7 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin Dmitry Osipenko + ` (20 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add lockless drm_gem_shmem_get_pages() helper that skips taking reservation +lock if pages_use_count is non-zero, leveraging from atomicity of the +refcount_t. Make drm_gem_shmem_mmap() to utilize the new helper. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index cacf0f8c42e2..1c032513abf1 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -226,6 +226,20 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + ++static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) ++{ ++ int ret; ++ ++ if (refcount_inc_not_zero(&shmem->pages_use_count)) ++ return 0; ++ ++ dma_resv_lock(shmem->base.resv, NULL); ++ ret = drm_gem_shmem_get_pages_locked(shmem); ++ dma_resv_unlock(shmem->base.resv); ++ ++ return ret; ++} ++ + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { + int ret; +@@ -609,10 +623,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct + return ret; + } + +- dma_resv_lock(shmem->base.resv, NULL); +- ret = drm_gem_shmem_get_pages_locked(shmem); +- dma_resv_unlock(shmem->base.resv); +- ++ ret = drm_gem_shmem_get_pages(shmem); + if (ret) + return ret; + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (8 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count Dmitry Osipenko + ` (19 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +The vmapped pages shall be pinned in memory and previously get/put_pages() +were implicitly hard-pinning/unpinning the pages. This will no longer be +the case with addition of memory shrinker because pages_use_count > 0 won't +determine anymore whether pages are hard-pinned (they will be soft-pinned), +while the new pages_pin_count will do the hard-pinning. Switch the +vmap/vunmap() to use pin/unpin() functions in a preparation of addition +of the memory shrinker support to drm-shmem. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 19 ++++++++++++------- + include/drm/drm_gem_shmem_helper.h | 2 +- + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 1c032513abf1..9c89183f81b7 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -256,6 +256,14 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + return ret; + } + ++static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) ++{ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (refcount_dec_and_test(&shmem->pages_pin_count)) ++ drm_gem_shmem_put_pages_locked(shmem); ++} ++ + /** + * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object + * @shmem: shmem GEM object +@@ -303,10 +311,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + return; + + dma_resv_lock(shmem->base.resv, NULL); +- +- if (refcount_dec_and_test(&shmem->pages_pin_count)) +- drm_gem_shmem_put_pages_locked(shmem); +- ++ drm_gem_shmem_unpin_locked(shmem); + dma_resv_unlock(shmem->base.resv); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); +@@ -344,7 +349,7 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + return 0; + } + +- ret = drm_gem_shmem_get_pages_locked(shmem); ++ ret = drm_gem_shmem_pin_locked(shmem); + if (ret) + goto err_zero_use; + +@@ -367,7 +372,7 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + + err_put_pages: + if (!obj->import_attach) +- drm_gem_shmem_put_pages_locked(shmem); ++ drm_gem_shmem_unpin_locked(shmem); + err_zero_use: + shmem->vmap_use_count = 0; + +@@ -404,7 +409,7 @@ void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, + return; + + vunmap(shmem->vaddr); +- drm_gem_shmem_put_pages_locked(shmem); ++ drm_gem_shmem_unpin_locked(shmem); + } + + shmem->vaddr = NULL; +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 2c5dc62df20c..80623b897803 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -124,7 +124,7 @@ int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv); + static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) + { + return (shmem->madv > 0) && +- !shmem->vmap_use_count && shmem->sgt && ++ !refcount_read(&shmem->pages_pin_count) && shmem->sgt && + !shmem->base.dma_buf && !shmem->base.import_attach; + } + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (9 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition Dmitry Osipenko + ` (18 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Use refcount_t helper for vmap_use_count to make refcounting consistent +with pages_use_count and pages_pin_count that use refcount_t. This also +makes vmapping to benefit from the refcount_t's overflow checks. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 28 +++++++++++--------------- + include/drm/drm_gem_shmem_helper.h | 2 +- + 2 files changed, 13 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 9c89183f81b7..3403700780c3 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -144,7 +144,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + } else { + dma_resv_lock(shmem->base.resv, NULL); + +- drm_WARN_ON(obj->dev, shmem->vmap_use_count); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); + + if (shmem->sgt) { + dma_unmap_sgtable(obj->dev->dev, shmem->sgt, +@@ -344,23 +344,25 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + + dma_resv_assert_held(shmem->base.resv); + +- if (shmem->vmap_use_count++ > 0) { ++ if (refcount_inc_not_zero(&shmem->vmap_use_count)) { + iosys_map_set_vaddr(map, shmem->vaddr); + return 0; + } + + ret = drm_gem_shmem_pin_locked(shmem); + if (ret) +- goto err_zero_use; ++ return ret; + + if (shmem->map_wc) + prot = pgprot_writecombine(prot); + shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, + VM_MAP, prot); +- if (!shmem->vaddr) ++ if (!shmem->vaddr) { + ret = -ENOMEM; +- else ++ } else { + iosys_map_set_vaddr(map, shmem->vaddr); ++ refcount_set(&shmem->vmap_use_count, 1); ++ } + } + + if (ret) { +@@ -373,8 +375,6 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + err_put_pages: + if (!obj->import_attach) + drm_gem_shmem_unpin_locked(shmem); +-err_zero_use: +- shmem->vmap_use_count = 0; + + return ret; + } +@@ -402,14 +402,10 @@ void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, + } else { + dma_resv_assert_held(shmem->base.resv); + +- if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count)) +- return; +- +- if (--shmem->vmap_use_count > 0) +- return; +- +- vunmap(shmem->vaddr); +- drm_gem_shmem_unpin_locked(shmem); ++ if (refcount_dec_and_test(&shmem->vmap_use_count)) { ++ vunmap(shmem->vaddr); ++ drm_gem_shmem_unpin_locked(shmem); ++ } + } + + shmem->vaddr = NULL; +@@ -655,7 +651,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + + drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); + drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); +- drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); ++ drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count)); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 80623b897803..18020f653d7e 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -82,7 +82,7 @@ struct drm_gem_shmem_object { + * Reference count on the virtual address. + * The address are un-mapped when the count reaches zero. + */ +- unsigned int vmap_use_count; ++ refcount_t vmap_use_count; + + /** + * @pages_mark_dirty_on_put: +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (10 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public Dmitry Osipenko + ` (17 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Prepare drm_gem_shmem_free() to addition of memory shrinker support +to drm-shmem by adding and using variant of put_pages() that doesn't +touch reservation lock. Reservation shouldn't be touched because lockdep +will trigger a bogus warning about locking contention with fs_reclaim +code paths that can't happen during the time when GEM is freed and +lockdep doesn't know about that. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 40 ++++++++++++++------------ + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 3403700780c3..799a3c5015ad 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -128,6 +128,22 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_create); + ++static void ++drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ ++#ifdef CONFIG_X86 ++ if (shmem->map_wc) ++ set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); ++#endif ++ ++ drm_gem_put_pages(obj, shmem->pages, ++ shmem->pages_mark_dirty_on_put, ++ shmem->pages_mark_accessed_on_put); ++ shmem->pages = NULL; ++} ++ + /** + * drm_gem_shmem_free - Free resources associated with a shmem GEM object + * @shmem: shmem GEM object to free +@@ -142,8 +158,6 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + if (obj->import_attach) { + drm_prime_gem_destroy(obj, shmem->sgt); + } else { +- dma_resv_lock(shmem->base.resv, NULL); +- + drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); + + if (shmem->sgt) { +@@ -152,13 +166,12 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + sg_free_table(shmem->sgt); + kfree(shmem->sgt); + } +- if (shmem->pages) +- drm_gem_shmem_put_pages_locked(shmem); ++ if (shmem->pages && ++ refcount_dec_and_test(&shmem->pages_use_count)) ++ drm_gem_shmem_free_pages(shmem); + + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); +- +- dma_resv_unlock(shmem->base.resv); + } + + drm_gem_object_release(obj); +@@ -208,21 +221,10 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + */ + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + { +- struct drm_gem_object *obj = &shmem->base; +- + dma_resv_assert_held(shmem->base.resv); + +- if (refcount_dec_and_test(&shmem->pages_use_count)) { +-#ifdef CONFIG_X86 +- if (shmem->map_wc) +- set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); +-#endif +- +- drm_gem_put_pages(obj, shmem->pages, +- shmem->pages_mark_dirty_on_put, +- shmem->pages_mark_accessed_on_put); +- shmem->pages = NULL; +- } ++ if (refcount_dec_and_test(&shmem->pages_use_count)) ++ drm_gem_shmem_free_pages(shmem); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (11 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() Dmitry Osipenko + ` (16 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +We're going to move away from having implicit get_pages() done by +get_pages_sgt() to simplify refcnt handling. Drivers will manage +get/put_pages() by themselves. Expose the drm_gem_shmem_get_pages() +in a public drm-shmem API. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 10 +++++++++- + include/drm/drm_gem_shmem_helper.h | 1 + + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 799a3c5015ad..dc416a4bce1b 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -228,7 +228,14 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) ++/* ++ * drm_gem_shmem_get_pages - Increase use count on the backing pages for a shmem GEM object ++ * @shmem: shmem GEM object ++ * ++ * This function Increases the use count and allocates the backing pages if ++ * use-count equals to zero. ++ */ ++int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + { + int ret; + +@@ -241,6 +248,7 @@ static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + + return ret; + } ++EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages); + + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 18020f653d7e..6dedc0739fbc 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -110,6 +110,7 @@ struct drm_gem_shmem_object { + struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size); + void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); + ++int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); + int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (12 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released Dmitry Osipenko + ` (15 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +We're going to move away from having implicit get_pages() done by +get_pages_sgt() to ease simplify refcnt handling. Drivers will manage +get/put_pages() by themselves. Add drm_gem_shmem_put_pages(). + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 20 ++++++++++++++++++++ + include/drm/drm_gem_shmem_helper.h | 1 + + 2 files changed, 21 insertions(+) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index dc416a4bce1b..f5ed64f78648 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -218,6 +218,7 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + * @shmem: shmem GEM object + * + * This function decreases the use count and puts the backing pages when use drops to zero. ++ * Caller must hold GEM's reservation lock. + */ + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + { +@@ -228,6 +229,25 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + ++/* ++ * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a shmem GEM object ++ * @shmem: shmem GEM object ++ * ++ * This function decreases the use count and puts the backing pages when use drops to zero. ++ * It's unlocked version of drm_gem_shmem_put_pages_locked(), caller must not hold ++ * GEM's reservation lock. ++ */ ++void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) ++{ ++ if (refcount_dec_not_one(&shmem->pages_use_count)) ++ return; ++ ++ dma_resv_lock(shmem->base.resv, NULL); ++ drm_gem_shmem_put_pages_locked(shmem); ++ dma_resv_unlock(shmem->base.resv); ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); ++ + /* + * drm_gem_shmem_get_pages - Increase use count on the backing pages for a shmem GEM object + * @shmem: shmem GEM object +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 6dedc0739fbc..525480488451 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -111,6 +111,7 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t + void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); + + int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem); ++void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); + int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (13 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages Dmitry Osipenko + ` (14 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +All drivers will be moved to get/put pages explicitly and then the last +put_pages() will be invoked during gem_free() time by some drivers. +We can't touch reservation lock when GEM is freed because that will cause +a spurious warning from lockdep when shrinker support will be added. +Lockdep doesn't know that fs_reclaim isn't functioning for a freed object, +and thus, can't deadlock. Release pages directly without taking reservation +lock if GEM is freed and its refcount is zero. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index f5ed64f78648..c7357110ca76 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -242,6 +242,22 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) + if (refcount_dec_not_one(&shmem->pages_use_count)) + return; + ++ /* ++ * Destroying the object is a special case because acquiring ++ * the obj lock can cause a locking order inversion between ++ * reservation_ww_class_mutex and fs_reclaim. ++ * ++ * This deadlock is not actually possible, because no one should ++ * be already holding the lock when GEM is released. Unfortunately ++ * lockdep is not aware of this detail. So when the refcount drops ++ * to zero, we pretend it is already locked. ++ */ ++ if (!kref_read(&shmem->base.refcount)) { ++ if (refcount_dec_and_test(&shmem->pages_use_count)) ++ drm_gem_shmem_free_pages(shmem); ++ return; ++ } ++ + dma_resv_lock(shmem->base.resv, NULL); + drm_gem_shmem_put_pages_locked(shmem); + dma_resv_unlock(shmem->base.resv); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (14 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Dmitry Osipenko + ` (13 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +To simplify the drm-shmem refcnt handling, we're moving away from +the implicit get_pages() that is used by get_pages_sgt(). From now on +drivers will have to pin pages while they use sgt. Lima driver doesn't +have shrinker, hence pages are pinned and sgt is valid as long as pages' +use-count > 0. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/lima/lima_gem.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index 2a97aa85416b..9c3e34a7fbed 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -115,6 +115,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + return PTR_ERR(shmem); + + obj = &shmem->base; ++ bo = to_lima_bo(obj); + + /* Mali Utgard GPU can only support 32bit address space */ + mask = mapping_gfp_mask(obj->filp->f_mapping); +@@ -123,13 +124,17 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + mapping_set_gfp_mask(obj->filp->f_mapping, mask); + + if (is_heap) { +- bo = to_lima_bo(obj); + err = lima_heap_alloc(bo, NULL); + if (err) + goto out; + } else { +- struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem); ++ struct sg_table *sgt; + ++ err = drm_gem_shmem_get_pages(shmem); ++ if (err) ++ goto out; ++ ++ sgt = drm_gem_shmem_get_pages_sgt(shmem); + if (IS_ERR(sgt)) { + err = PTR_ERR(sgt); + goto out; +@@ -139,6 +144,9 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + err = drm_gem_handle_create(file, obj, handle); + + out: ++ if (err && refcount_read(&bo->base.pages_use_count)) ++ drm_gem_shmem_put_pages(shmem); ++ + /* drop reference from allocate - handle holds it now */ + drm_gem_object_put(obj); + +@@ -152,6 +160,9 @@ static void lima_gem_free_object(struct drm_gem_object *obj) + if (!list_empty(&bo->va)) + dev_err(obj->dev->dev, "lima gem free bo still has va\n"); + ++ if (refcount_read(&bo->base.pages_use_count)) ++ drm_gem_shmem_put_pages(&bo->base); ++ + drm_gem_shmem_free(&bo->base); + } + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (15 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages Dmitry Osipenko + ` (12 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +From: Boris Brezillon + +If some the pages or sgt allocation failed, we shouldn't release the +pages ref we got earlier, otherwise we will end up with unbalanced +get/put_pages() calls. We should instead leave everything in place +and let the BO release function deal with extra cleanup when the object +is destroyed, or let the fault handler try again next time it's called. + +Fixes: 187d2929206e ("drm/panfrost: Add support for GPU heap allocations") +Cc: +Signed-off-by: Boris Brezillon +Co-developed-by: Dmitry Osipenko +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index bd5a0073009d..4a0b4bf03f1a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -502,11 +502,18 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + mapping_set_unevictable(mapping); + + for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) { ++ /* Can happen if the last fault only partially filled this ++ * section of the pages array before failing. In that case ++ * we skip already filled pages. ++ */ ++ if (pages[i]) ++ continue; ++ + pages[i] = shmem_read_mapping_page(mapping, i); + if (IS_ERR(pages[i])) { + ret = PTR_ERR(pages[i]); + pages[i] = NULL; +- goto err_pages; ++ goto err_unlock; + } + } + +@@ -514,7 +521,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + ret = sg_alloc_table_from_pages(sgt, pages + page_offset, + NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL); + if (ret) +- goto err_pages; ++ goto err_unlock; + + ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0); + if (ret) +@@ -537,8 +544,6 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + + err_map: + sg_free_table(sgt); +-err_pages: +- drm_gem_shmem_put_pages_locked(&bo->base); + err_unlock: + dma_resv_unlock(obj->resv); + err_bo: +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (16 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 19/30] drm/virtio: " Dmitry Osipenko + ` (11 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +To simplify the drm-shmem refcnt handling, we're moving away from +the implicit get_pages() that is used by get_pages_sgt(). From now on +drivers will have to pin pages while they use sgt. Panfrost's shrinker +doesn't support swapping out BOs, hence pages are pinned and sgt is valid +as long as pages' use-count > 0. + +In Panfrost, panfrost_gem_mapping, which is the object representing a +GPU mapping of a BO, owns a pages ref. This guarantees that any BO being +mapped GPU side has its pages retained till the mapping is destroyed. + +Since pages are no longer guaranteed to stay pinned for the BO lifetime, +and MADVISE(DONT_NEED) flagging remains after the GEM handle has been +destroyed, we need to add an extra 'is_purgeable' check in +panfrost_gem_purge(), to make sure we're not trying to purge a BO that +already had its pages released. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/panfrost/panfrost_gem.c | 63 ++++++++++++++----- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 6 ++ + 2 files changed, 52 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index f268bd5c2884..7edfc12f7c1f 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -35,20 +35,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) + */ + WARN_ON_ONCE(!list_empty(&bo->mappings.list)); + +- if (bo->sgts) { +- int i; +- int n_sgt = bo->base.base.size / SZ_2M; +- +- for (i = 0; i < n_sgt; i++) { +- if (bo->sgts[i].sgl) { +- dma_unmap_sgtable(pfdev->dev, &bo->sgts[i], +- DMA_BIDIRECTIONAL, 0); +- sg_free_table(&bo->sgts[i]); +- } +- } +- kvfree(bo->sgts); +- } +- + drm_gem_shmem_free(&bo->base); + } + +@@ -85,11 +71,40 @@ panfrost_gem_teardown_mapping(struct panfrost_gem_mapping *mapping) + + static void panfrost_gem_mapping_release(struct kref *kref) + { +- struct panfrost_gem_mapping *mapping; +- +- mapping = container_of(kref, struct panfrost_gem_mapping, refcount); ++ struct panfrost_gem_mapping *mapping = ++ container_of(kref, struct panfrost_gem_mapping, refcount); ++ struct panfrost_gem_object *bo = mapping->obj; ++ struct panfrost_device *pfdev = bo->base.base.dev->dev_private; + + panfrost_gem_teardown_mapping(mapping); ++ ++ /* On heap BOs, release the sgts created in the fault handler path. */ ++ if (bo->sgts) { ++ int i, n_sgt = bo->base.base.size / SZ_2M; ++ ++ for (i = 0; i < n_sgt; i++) { ++ if (bo->sgts[i].sgl) { ++ dma_unmap_sgtable(pfdev->dev, &bo->sgts[i], ++ DMA_BIDIRECTIONAL, 0); ++ sg_free_table(&bo->sgts[i]); ++ } ++ } ++ kvfree(bo->sgts); ++ } ++ ++ /* Pages ref is owned by the panfrost_gem_mapping object. We must ++ * release our pages ref (if any), before releasing the object ++ * ref. ++ * Non-heap BOs acquired the pages at panfrost_gem_mapping creation ++ * time, and heap BOs may have acquired pages if the fault handler ++ * was called, in which case bo->sgts should be non-NULL. ++ */ ++ if (!bo->base.base.import_attach && (!bo->is_heap || bo->sgts) && ++ bo->base.madv >= 0) { ++ drm_gem_shmem_put_pages(&bo->base); ++ bo->sgts = NULL; ++ } ++ + drm_gem_object_put(&mapping->obj->base.base); + panfrost_mmu_ctx_put(mapping->mmu); + kfree(mapping); +@@ -125,6 +140,20 @@ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) + if (!mapping) + return -ENOMEM; + ++ if (!bo->is_heap && !bo->base.base.import_attach) { ++ /* Pages ref is owned by the panfrost_gem_mapping object. ++ * For non-heap BOs, we request pages at mapping creation ++ * time, such that the panfrost_mmu_map() call, further down in ++ * this function, is guaranteed to have pages_use_count > 0 ++ * when drm_gem_shmem_get_pages_sgt() is called. ++ */ ++ ret = drm_gem_shmem_get_pages(&bo->base); ++ if (ret) { ++ kfree(mapping); ++ return ret; ++ } ++ } ++ + INIT_LIST_HEAD(&mapping->node); + kref_init(&mapping->refcount); + drm_gem_object_get(obj); +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +index 02b60ea1433a..d4fb0854cf2f 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +@@ -50,6 +50,12 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) + if (!dma_resv_trylock(shmem->base.resv)) + goto unlock_mappings; + ++ /* BO might have become unpurgeable if the last pages_use_count ref ++ * was dropped, but the BO hasn't been destroyed yet. ++ */ ++ if (!drm_gem_shmem_is_purgeable(shmem)) ++ goto unlock_mappings; ++ + panfrost_gem_teardown_mappings_locked(bo); + drm_gem_shmem_purge_locked(&bo->base); + ret = true; +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 19/30] drm/virtio: Explicitly get and put drm-shmem pages + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (17 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 20/30] drm/v3d: " Dmitry Osipenko + ` (10 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +We're moving away from implicit get_pages() that is done by +get_pages_sgt() to simplify the refcnt handling. Drivers will have +to pin pages while they use sgt. VirtIO-GPU doesn't support shrinker, +hence pages are pinned and sgt is valid as long as pages' use-count > 0. + +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_object.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index c7e74cf13022..e58528c562ef 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -67,6 +67,7 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) + + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); + if (virtio_gpu_is_shmem(bo)) { ++ drm_gem_shmem_put_pages(&bo->base); + drm_gem_shmem_free(&bo->base); + } else if (virtio_gpu_is_vram(bo)) { + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); +@@ -196,9 +197,13 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + return PTR_ERR(shmem_obj); + bo = gem_to_virtio_gpu_obj(&shmem_obj->base); + ++ ret = drm_gem_shmem_get_pages(shmem_obj); ++ if (ret) ++ goto err_free_gem; ++ + ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle); + if (ret < 0) +- goto err_free_gem; ++ goto err_put_pages; + + bo->dumb = params->dumb; + +@@ -243,6 +248,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + kvfree(ents); + err_put_id: + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); ++err_put_pages: ++ drm_gem_shmem_put_pages(shmem_obj); + err_free_gem: + drm_gem_shmem_free(shmem_obj); + return ret; +-- +2.43.0 + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 21/30] drm/shmem-helper: Change sgt allocation policy + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (19 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 20/30] drm/v3d: " Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker Dmitry Osipenko + ` (8 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +In a preparation to addition of drm-shmem memory shrinker support, change +the SGT allocation policy in this way: + +1. SGT can be allocated only if shmem pages are pinned at the +time of allocation, otherwise allocation fails. + +2. Drivers must ensure that pages are pinned during the time of SGT usage +and should get new SGT if pages were unpinned. + +This new policy is required by the shrinker because it will move pages +to/from SWAP unless pages are pinned, invalidating SGT pointer once pages +are relocated. + +Previous patches prepared drivers to the new policy. + +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 55 ++++++++++++++------------ + 1 file changed, 29 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index c7357110ca76..ff5437ab2c95 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -133,6 +133,14 @@ drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + ++ if (shmem->sgt) { ++ dma_unmap_sgtable(obj->dev->dev, shmem->sgt, ++ DMA_BIDIRECTIONAL, 0); ++ sg_free_table(shmem->sgt); ++ kfree(shmem->sgt); ++ shmem->sgt = NULL; ++ } ++ + #ifdef CONFIG_X86 + if (shmem->map_wc) + set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); +@@ -155,24 +163,12 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + +- if (obj->import_attach) { ++ if (obj->import_attach) + drm_prime_gem_destroy(obj, shmem->sgt); +- } else { +- drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); + +- if (shmem->sgt) { +- dma_unmap_sgtable(obj->dev->dev, shmem->sgt, +- DMA_BIDIRECTIONAL, 0); +- sg_free_table(shmem->sgt); +- kfree(shmem->sgt); +- } +- if (shmem->pages && +- refcount_dec_and_test(&shmem->pages_use_count)) +- drm_gem_shmem_free_pages(shmem); +- +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); +- } ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); + + drm_gem_object_release(obj); + kfree(shmem); +@@ -722,6 +718,9 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) + + drm_WARN_ON(obj->dev, obj->import_attach); + ++ if (drm_WARN_ON(obj->dev, !shmem->pages)) ++ return ERR_PTR(-ENOMEM); ++ + return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); +@@ -737,15 +736,10 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + + drm_WARN_ON(obj->dev, obj->import_attach); + +- ret = drm_gem_shmem_get_pages_locked(shmem); +- if (ret) +- return ERR_PTR(ret); +- + sgt = drm_gem_shmem_get_sg_table(shmem); +- if (IS_ERR(sgt)) { +- ret = PTR_ERR(sgt); +- goto err_put_pages; +- } ++ if (IS_ERR(sgt)) ++ return sgt; ++ + /* Map the pages for use by the h/w. */ + ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0); + if (ret) +@@ -758,8 +752,6 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + err_free_sgt: + sg_free_table(sgt); + kfree(sgt); +-err_put_pages: +- drm_gem_shmem_put_pages_locked(shmem); + return ERR_PTR(ret); + } + +@@ -776,6 +768,17 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + * and difference between dma-buf imported and natively allocated objects. + * drm_gem_shmem_get_sg_table() should not be directly called by drivers. + * ++ * Drivers should adhere to these SGT usage rules: ++ * ++ * 1. SGT should be allocated only if shmem pages are pinned at the ++ * time of allocation, otherwise allocation will fail. ++ * ++ * 2. Drivers should ensure that pages are pinned during the time of ++ * SGT usage and should get new SGT if pages were unpinned. ++ * ++ * Drivers don't own returned SGT and must take care of the SGT pointer ++ * lifetime. SGT is valid as long as GEM pages that backing SGT are pinned. ++ * + * Returns: + * A pointer to the scatter/gather table of pinned pages or errno on failure. + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (20 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 21/30] drm/shmem-helper: Change sgt allocation policy Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() Dmitry Osipenko + ` (7 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Introduce common drm-shmem shrinker for DRM drivers. + +To start using drm-shmem shrinker drivers should do the following: + +1. Implement evict() callback of GEM object where driver should check + whether object is purgeable or evictable using drm-shmem helpers and + perform the shrinking action + +2. Initialize drm-shmem internals using drmm_gem_shmem_init(drm_device), + which will register drm-shmem shrinker + +3. Implement madvise IOCTL that will use drm_gem_shmem_madvise() + +Signed-off-by: Daniel Almeida +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 365 +++++++++++++++++- + drivers/gpu/drm/panfrost/panfrost_gem.c | 3 +- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 13 +- + include/drm/drm_device.h | 10 +- + include/drm/drm_gem_shmem_helper.h | 68 +++- + 5 files changed, 433 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index ff5437ab2c95..59cebd1e35af 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -128,11 +129,49 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_create); + ++static bool drm_gem_shmem_is_evictable(struct drm_gem_shmem_object *shmem) ++{ ++ return (shmem->madv >= 0) && shmem->base.funcs->evict && ++ refcount_read(&shmem->pages_use_count) && ++ !refcount_read(&shmem->pages_pin_count) && ++ !shmem->base.dma_buf && !shmem->base.import_attach && ++ !shmem->evicted; ++} ++ ++static void ++drm_gem_shmem_shrinker_update_lru_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ struct drm_gem_shmem *shmem_mm = obj->dev->shmem_mm; ++ struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker; ++ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (!shmem_shrinker || obj->import_attach) ++ return; ++ ++ if (shmem->madv < 0) ++ drm_gem_lru_remove(&shmem->base); ++ else if (drm_gem_shmem_is_evictable(shmem) || drm_gem_shmem_is_purgeable(shmem)) ++ drm_gem_lru_move_tail(&shmem_shrinker->lru_evictable, &shmem->base); ++ else if (shmem->evicted) ++ drm_gem_lru_move_tail(&shmem_shrinker->lru_evicted, &shmem->base); ++ else if (!shmem->pages) ++ drm_gem_lru_remove(&shmem->base); ++ else ++ drm_gem_lru_move_tail(&shmem_shrinker->lru_pinned, &shmem->base); ++} ++ + static void + drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + ++ if (!shmem->pages) { ++ drm_WARN_ON(obj->dev, !shmem->evicted && shmem->madv >= 0); ++ return; ++ } ++ + if (shmem->sgt) { + dma_unmap_sgtable(obj->dev->dev, shmem->sgt, + DMA_BIDIRECTIONAL, 0); +@@ -175,15 +214,26 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_free); + +-static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) ++static int ++drm_gem_shmem_acquire_pages(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + struct page **pages; + ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return -EINVAL; ++ + dma_resv_assert_held(shmem->base.resv); + +- if (refcount_inc_not_zero(&shmem->pages_use_count)) ++ if (shmem->madv < 0) { ++ drm_WARN_ON(obj->dev, shmem->pages); ++ return -ENOMEM; ++ } ++ ++ if (shmem->pages) { ++ drm_WARN_ON(obj->dev, !shmem->evicted); + return 0; ++ } + + pages = drm_gem_get_pages(obj); + if (IS_ERR(pages)) { +@@ -204,8 +254,29 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + + shmem->pages = pages; + ++ return 0; ++} ++ ++static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) ++{ ++ int err; ++ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (shmem->madv < 0) ++ return -ENOMEM; ++ ++ if (refcount_inc_not_zero(&shmem->pages_use_count)) ++ return 0; ++ ++ err = drm_gem_shmem_acquire_pages(shmem); ++ if (err) ++ return err; ++ + refcount_set(&shmem->pages_use_count, 1); + ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++ + return 0; + } + +@@ -222,6 +293,8 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + + if (refcount_dec_and_test(&shmem->pages_use_count)) + drm_gem_shmem_free_pages(shmem); ++ ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +@@ -266,6 +339,11 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); + * + * This function Increases the use count and allocates the backing pages if + * use-count equals to zero. ++ * ++ * Note that this function doesn't pin pages in memory. If your driver ++ * uses drm-shmem shrinker, then it's free to relocate pages to swap. ++ * Getting pages only guarantees that pages are allocated, and not that ++ * pages reside in memory. In order to pin pages use drm_gem_shmem_pin(). + */ + int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + { +@@ -291,6 +369,10 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + if (refcount_inc_not_zero(&shmem->pages_pin_count)) + return 0; + ++ ret = drm_gem_shmem_swapin_locked(shmem); ++ if (ret) ++ return ret; ++ + ret = drm_gem_shmem_get_pages_locked(shmem); + if (!ret) + refcount_set(&shmem->pages_pin_count, 1); +@@ -489,29 +571,48 @@ int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv) + + madv = shmem->madv; + ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++ + return (madv >= 0); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked); + +-void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) ++int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) + { + struct drm_gem_object *obj = &shmem->base; +- struct drm_device *dev = obj->dev; ++ int ret; + +- dma_resv_assert_held(shmem->base.resv); ++ ret = dma_resv_lock_interruptible(obj->resv, NULL); ++ if (ret) ++ return ret; + +- drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem)); ++ ret = drm_gem_shmem_madvise_locked(shmem, madv); ++ dma_resv_unlock(obj->resv); + +- dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0); +- sg_free_table(shmem->sgt); +- kfree(shmem->sgt); +- shmem->sgt = NULL; ++ return ret; ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise); + +- drm_gem_shmem_put_pages_locked(shmem); ++static void ++drm_gem_shmem_shrinker_put_pages_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ struct drm_device *dev = obj->dev; + +- shmem->madv = -1; ++ dma_resv_assert_held(shmem->base.resv); + ++ if (shmem->evicted) ++ return; ++ ++ drm_gem_shmem_free_pages(shmem); + drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping); ++} ++ ++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ ++ drm_gem_shmem_shrinker_put_pages_locked(shmem); + drm_gem_free_mmap_offset(obj); + + /* Our goal here is to return as much of the memory as +@@ -522,9 +623,45 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) + shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1); + + invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); ++ ++ shmem->madv = -1; ++ shmem->evicted = false; ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked); + ++/** ++ * drm_gem_shmem_swapin_locked() - Moves shmem GEM back to memory and enables ++ * hardware access to the memory. ++ * @shmem: shmem GEM object ++ * ++ * This function moves shmem GEM back to memory if it was previously evicted ++ * by the memory shrinker. The GEM is ready to use on success. ++ * ++ * Returns: ++ * 0 on success or a negative error code on failure. ++ */ ++int drm_gem_shmem_swapin_locked(struct drm_gem_shmem_object *shmem) ++{ ++ int err; ++ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (!shmem->evicted) ++ return 0; ++ ++ err = drm_gem_shmem_acquire_pages(shmem); ++ if (err) ++ return err; ++ ++ shmem->evicted = false; ++ ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_swapin_locked); ++ + /** + * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object + * @file: DRM file structure to create the dumb buffer for +@@ -571,22 +708,32 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) + vm_fault_t ret; + struct page *page; + pgoff_t page_offset; ++ int err; + + /* We don't use vmf->pgoff since that has the fake offset */ + page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; + + dma_resv_lock(shmem->base.resv, NULL); + +- if (page_offset >= num_pages || +- drm_WARN_ON_ONCE(obj->dev, !shmem->pages) || +- shmem->madv < 0) { ++ err = drm_gem_shmem_swapin_locked(shmem); ++ if (err) { ++ ret = VM_FAULT_OOM; ++ goto unlock; ++ } ++ ++ if (page_offset >= num_pages || !shmem->pages) { + ret = VM_FAULT_SIGBUS; + } else { ++ /* ++ * shmem->pages is guaranteed to be valid while reservation ++ * lock is held and drm_gem_shmem_swapin_locked() succeeds. ++ */ + page = shmem->pages[page_offset]; + + ret = vmf_insert_pfn(vma, vmf->address, page_to_pfn(page)); + } + ++unlock: + dma_resv_unlock(shmem->base.resv); + + return ret; +@@ -609,6 +756,7 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) + drm_WARN_ON_ONCE(obj->dev, + !refcount_inc_not_zero(&shmem->pages_use_count)); + ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); + dma_resv_unlock(shmem->base.resv); + + drm_gem_vm_open(vma); +@@ -694,7 +842,9 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); + drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); + drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count)); ++ drm_printf_indent(p, indent, "evicted=%d\n", shmem->evicted); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); ++ drm_printf_indent(p, indent, "madv=%d\n", shmem->madv); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); + +@@ -784,8 +934,13 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + */ + struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) + { +- int ret; ++ struct drm_gem_object *obj = &shmem->base; + struct sg_table *sgt; ++ int ret; ++ ++ if (drm_WARN_ON(obj->dev, drm_gem_shmem_is_evictable(shmem)) || ++ drm_WARN_ON(obj->dev, drm_gem_shmem_is_purgeable(shmem))) ++ return ERR_PTR(-EBUSY); + + ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); + if (ret) +@@ -832,6 +987,184 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table); + ++static unsigned long ++drm_gem_shmem_shrinker_count_objects(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = shrinker->private_data; ++ unsigned long count = shmem_shrinker->lru_evictable.count; ++ ++ if (count >= SHRINK_EMPTY) ++ return SHRINK_EMPTY - 1; ++ ++ return count ?: SHRINK_EMPTY; ++} ++ ++void drm_gem_shmem_evict_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ ++ drm_WARN_ON(obj->dev, !drm_gem_shmem_is_evictable(shmem)); ++ drm_WARN_ON(obj->dev, shmem->evicted); ++ ++ drm_gem_shmem_shrinker_put_pages_locked(shmem); ++ ++ shmem->evicted = true; ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_evict_locked); ++ ++static bool drm_gem_shmem_shrinker_evict_locked(struct drm_gem_object *obj) ++{ ++ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); ++ int err; ++ ++ if (!drm_gem_shmem_is_evictable(shmem) || ++ get_nr_swap_pages() < obj->size >> PAGE_SHIFT) ++ return false; ++ ++ err = drm_gem_evict_locked(obj); ++ if (err) ++ return false; ++ ++ return true; ++} ++ ++static bool drm_gem_shmem_shrinker_purge_locked(struct drm_gem_object *obj) ++{ ++ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); ++ int err; ++ ++ if (!drm_gem_shmem_is_purgeable(shmem)) ++ return false; ++ ++ err = drm_gem_evict_locked(obj); ++ if (err) ++ return false; ++ ++ return true; ++} ++ ++static unsigned long ++drm_gem_shmem_shrinker_scan_objects(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = shrinker->private_data; ++ unsigned long nr_to_scan = sc->nr_to_scan; ++ unsigned long remaining = 0; ++ unsigned long freed = 0; ++ ++ /* purge as many objects as we can */ ++ freed += drm_gem_lru_scan(&shmem_shrinker->lru_evictable, ++ nr_to_scan, &remaining, ++ drm_gem_shmem_shrinker_purge_locked); ++ ++ /* evict as many objects as we can */ ++ if (freed < nr_to_scan) ++ freed += drm_gem_lru_scan(&shmem_shrinker->lru_evictable, ++ nr_to_scan - freed, &remaining, ++ drm_gem_shmem_shrinker_evict_locked); ++ ++ return (freed > 0 && remaining > 0) ? freed : SHRINK_STOP; ++} ++ ++static int drm_gem_shmem_shrinker_init(struct drm_gem_shmem *shmem_mm, ++ const char *shrinker_name) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker; ++ struct shrinker *shrinker; ++ ++ shrinker = shrinker_alloc(0, shrinker_name); ++ if (!shrinker) ++ return -ENOMEM; ++ ++ shrinker->count_objects = drm_gem_shmem_shrinker_count_objects; ++ shrinker->scan_objects = drm_gem_shmem_shrinker_scan_objects; ++ shrinker->private_data = shmem_shrinker; ++ shrinker->seeks = DEFAULT_SEEKS; ++ ++ mutex_init(&shmem_shrinker->lock); ++ shmem_shrinker->shrinker = shrinker; ++ drm_gem_lru_init(&shmem_shrinker->lru_evictable, &shmem_shrinker->lock); ++ drm_gem_lru_init(&shmem_shrinker->lru_evicted, &shmem_shrinker->lock); ++ drm_gem_lru_init(&shmem_shrinker->lru_pinned, &shmem_shrinker->lock); ++ ++ shrinker_register(shrinker); ++ ++ return 0; ++} ++ ++static void drm_gem_shmem_shrinker_release(struct drm_device *dev, ++ struct drm_gem_shmem *shmem_mm) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker; ++ ++ shrinker_free(shmem_shrinker->shrinker); ++ drm_WARN_ON(dev, !list_empty(&shmem_shrinker->lru_evictable.list)); ++ drm_WARN_ON(dev, !list_empty(&shmem_shrinker->lru_evicted.list)); ++ drm_WARN_ON(dev, !list_empty(&shmem_shrinker->lru_pinned.list)); ++ mutex_destroy(&shmem_shrinker->lock); ++} ++ ++static int drm_gem_shmem_init(struct drm_device *dev) ++{ ++ int err; ++ ++ if (drm_WARN_ON(dev, dev->shmem_mm)) ++ return -EBUSY; ++ ++ dev->shmem_mm = kzalloc(sizeof(*dev->shmem_mm), GFP_KERNEL); ++ if (!dev->shmem_mm) ++ return -ENOMEM; ++ ++ err = drm_gem_shmem_shrinker_init(dev->shmem_mm, dev->unique); ++ if (err) ++ goto free_gem_shmem; ++ ++ return 0; ++ ++free_gem_shmem: ++ kfree(dev->shmem_mm); ++ dev->shmem_mm = NULL; ++ ++ return err; ++} ++ ++static void drm_gem_shmem_release(struct drm_device *dev, void *ptr) ++{ ++ struct drm_gem_shmem *shmem_mm = dev->shmem_mm; ++ ++ drm_gem_shmem_shrinker_release(dev, shmem_mm); ++ dev->shmem_mm = NULL; ++ kfree(shmem_mm); ++} ++ ++/** ++ * drmm_gem_shmem_init() - Initialize drm-shmem internals ++ * @dev: DRM device ++ * ++ * Cleanup is automatically managed as part of DRM device releasing. ++ * Calling this function multiple times will result in a error. ++ * ++ * Returns: ++ * 0 on success or a negative error code on failure. ++ */ ++int drmm_gem_shmem_init(struct drm_device *dev) ++{ ++ int err; ++ ++ err = drm_gem_shmem_init(dev); ++ if (err) ++ return err; ++ ++ err = drmm_add_action_or_reset(dev, drm_gem_shmem_release, NULL); ++ if (err) ++ return err; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(drmm_gem_shmem_init); ++ + MODULE_DESCRIPTION("DRM SHMEM memory-management helpers"); + MODULE_IMPORT_NS(DMA_BUF); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index 7edfc12f7c1f..8c26b7e41b95 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -99,8 +99,7 @@ static void panfrost_gem_mapping_release(struct kref *kref) + * time, and heap BOs may have acquired pages if the fault handler + * was called, in which case bo->sgts should be non-NULL. + */ +- if (!bo->base.base.import_attach && (!bo->is_heap || bo->sgts) && +- bo->base.madv >= 0) { ++ if (!bo->base.base.import_attach && (!bo->is_heap || bo->sgts)) { + drm_gem_shmem_put_pages(&bo->base); + bo->sgts = NULL; + } +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +index d4fb0854cf2f..7b4deba803ed 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +@@ -15,6 +15,13 @@ + #include "panfrost_gem.h" + #include "panfrost_mmu.h" + ++static bool panfrost_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) ++{ ++ return (shmem->madv > 0) && ++ !refcount_read(&shmem->pages_pin_count) && shmem->sgt && ++ !shmem->base.dma_buf && !shmem->base.import_attach; ++} ++ + static unsigned long + panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) + { +@@ -26,7 +33,7 @@ panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc + return 0; + + list_for_each_entry(shmem, &pfdev->shrinker_list, madv_list) { +- if (drm_gem_shmem_is_purgeable(shmem)) ++ if (panfrost_gem_shmem_is_purgeable(shmem)) + count += shmem->base.size >> PAGE_SHIFT; + } + +@@ -53,7 +60,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) + /* BO might have become unpurgeable if the last pages_use_count ref + * was dropped, but the BO hasn't been destroyed yet. + */ +- if (!drm_gem_shmem_is_purgeable(shmem)) ++ if (!panfrost_gem_shmem_is_purgeable(shmem)) + goto unlock_mappings; + + panfrost_gem_teardown_mappings_locked(bo); +@@ -80,7 +87,7 @@ panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) + list_for_each_entry_safe(shmem, tmp, &pfdev->shrinker_list, madv_list) { + if (freed >= sc->nr_to_scan) + break; +- if (drm_gem_shmem_is_purgeable(shmem) && ++ if (panfrost_gem_shmem_is_purgeable(shmem) && + panfrost_gem_purge(&shmem->base)) { + freed += shmem->base.size >> PAGE_SHIFT; + list_del_init(&shmem->madv_list); +diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h +index 63767cf24371..6e729e716505 100644 +--- a/include/drm/drm_device.h ++++ b/include/drm/drm_device.h +@@ -15,6 +15,7 @@ struct drm_vblank_crtc; + struct drm_vma_offset_manager; + struct drm_vram_mm; + struct drm_fb_helper; ++struct drm_gem_shmem_shrinker; + + struct inode; + +@@ -289,8 +290,13 @@ struct drm_device { + /** @vma_offset_manager: GEM information */ + struct drm_vma_offset_manager *vma_offset_manager; + +- /** @vram_mm: VRAM MM memory manager */ +- struct drm_vram_mm *vram_mm; ++ union { ++ /** @vram_mm: VRAM MM memory manager */ ++ struct drm_vram_mm *vram_mm; ++ ++ /** @shmem_mm: SHMEM GEM memory manager */ ++ struct drm_gem_shmem *shmem_mm; ++ }; + + /** + * @switch_power_state: +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 525480488451..df97c11fc99a 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -13,6 +14,7 @@ + #include + + struct dma_buf_attachment; ++struct drm_device; + struct drm_mode_create_dumb; + struct drm_printer; + struct sg_table; +@@ -54,8 +56,8 @@ struct drm_gem_shmem_object { + * @madv: State for madvise + * + * 0 is active/inuse. ++ * 1 is not-needed/can-be-purged + * A negative value is the object is purged. +- * Positive values are driver specific and not used by the helpers. + */ + int madv; + +@@ -102,6 +104,14 @@ struct drm_gem_shmem_object { + * @map_wc: map object write-combined (instead of using shmem defaults). + */ + bool map_wc : 1; ++ ++ /** ++ * @evicted: True if shmem pages are evicted by the memory shrinker. ++ * Used internally by memory shrinker. The evicted pages can be ++ * moved back to memory using drm_gem_shmem_swapin_locked(), unlike ++ * the purged pages (madv < 0) that are destroyed permanently. ++ */ ++ bool evicted : 1; + }; + + #define to_drm_gem_shmem_obj(obj) \ +@@ -122,14 +132,19 @@ void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, + int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma); + + int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv); ++int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv); + + static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) + { +- return (shmem->madv > 0) && +- !refcount_read(&shmem->pages_pin_count) && shmem->sgt && ++ return (shmem->madv > 0) && shmem->base.funcs->evict && ++ refcount_read(&shmem->pages_use_count) && ++ !refcount_read(&shmem->pages_pin_count) && + !shmem->base.dma_buf && !shmem->base.import_attach; + } + ++int drm_gem_shmem_swapin_locked(struct drm_gem_shmem_object *shmem); ++ ++void drm_gem_shmem_evict_locked(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem); + + struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem); +@@ -273,6 +288,53 @@ static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct v + return drm_gem_shmem_mmap(shmem, vma); + } + ++/** ++ * drm_gem_shmem_object_madvise - unlocked GEM object function for drm_gem_shmem_madvise_locked() ++ * @obj: GEM object ++ * @madv: Madvise value ++ * ++ * This function wraps drm_gem_shmem_madvise_locked(), providing unlocked variant. ++ * ++ * Returns: ++ * 0 on success or a negative error code on failure. ++ */ ++static inline int drm_gem_shmem_object_madvise(struct drm_gem_object *obj, int madv) ++{ ++ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); ++ ++ return drm_gem_shmem_madvise(shmem, madv); ++} ++ ++/** ++ * struct drm_gem_shmem_shrinker - Memory shrinker of GEM shmem memory manager ++ */ ++struct drm_gem_shmem_shrinker { ++ /** @lock: Protects @lru_* */ ++ struct mutex lock; ++ ++ /** @shrinker: Shrinker for purging shmem GEM objects */ ++ struct shrinker *shrinker; ++ ++ /** @lru_pinned: List of pinned shmem GEM objects */ ++ struct drm_gem_lru lru_pinned; ++ ++ /** @lru_evictable: List of shmem GEM objects to be evicted */ ++ struct drm_gem_lru lru_evictable; ++ ++ /** @lru_evicted: List of evicted shmem GEM objects */ ++ struct drm_gem_lru lru_evicted; ++}; ++ ++/** ++ * struct drm_gem_shmem - GEM shmem memory manager ++ */ ++struct drm_gem_shmem { ++ /** @shrinker: GEM shmem shrinker */ ++ struct drm_gem_shmem_shrinker shrinker; ++}; ++ ++int drmm_gem_shmem_init(struct drm_device *dev); ++ + /* + * Driver ops + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (21 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() Dmitry Osipenko + ` (6 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Export drm_gem_shmem_get_pages_sgt_locked() that will be used by virtio-gpu +shrinker during GEM swap-in operation done under the held reservation lock. + +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +++++++++++++++++++++- + include/drm/drm_gem_shmem_helper.h | 1 + + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 59cebd1e35af..8fd7851c088b 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -875,12 +875,31 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); + +-static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) ++/** ++ * drm_gem_shmem_get_pages_sgt_locked - Provide a scatter/gather table of pinned ++ * pages for a shmem GEM object ++ * @shmem: shmem GEM object ++ * ++ * This is a locked version of @drm_gem_shmem_get_sg_table that exports a ++ * scatter/gather table suitable for PRIME usage by calling the standard ++ * DMA mapping API. ++ * ++ * Drivers must hold GEM's reservation lock when using this function. ++ * ++ * Drivers who need to acquire an scatter/gather table for objects need to call ++ * drm_gem_shmem_get_pages_sgt() instead. ++ * ++ * Returns: ++ * A pointer to the scatter/gather table of pinned pages or error pointer on failure. ++ */ ++struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + int ret; + struct sg_table *sgt; + ++ dma_resv_assert_held(shmem->base.resv); ++ + if (shmem->sgt) + return shmem->sgt; + +@@ -904,6 +923,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + kfree(sgt); + return ERR_PTR(ret); + } ++EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt_locked); + + /** + * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index df97c11fc99a..167f00f089de 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -149,6 +149,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem); + + struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem); + struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem); ++struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem); + + void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + struct drm_printer *p, unsigned int indent); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (22 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM Dmitry Osipenko + ` (5 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +SGT isn't refcounted. Once SGT pointer has been obtained, it remains the +same for both locked and unlocked get_pages_sgt(). Return cached SGT +directly without taking a potentially expensive lock. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 8fd7851c088b..e6e6e693ab95 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -962,6 +962,18 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) + drm_WARN_ON(obj->dev, drm_gem_shmem_is_purgeable(shmem))) + return ERR_PTR(-EBUSY); + ++ /* ++ * Drivers that use shrinker should take into account that shrinker ++ * may relocate BO, thus invalidating the returned SGT pointer. ++ * Such drivers should pin GEM while they use SGT. ++ * ++ * Drivers that don't use shrinker should take into account that ++ * SGT is released together with the GEM pages. Pages should be kept ++ * alive while SGT is used. ++ */ ++ if (shmem->sgt) ++ return shmem->sgt; ++ + ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); + if (ret) + return ERR_PTR(ret); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (23 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors Dmitry Osipenko + ` (4 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Don't free shmem object if it has pages that are in use at the time of +the GEM's freeing if DRM driver doesn't manage GEM/pages lifetime properly. +This prevents memory corruption due to the use-after-free bug in exchange +to leaking GEM. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index e6e6e693ab95..0d95d723b90d 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -205,9 +205,15 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + if (obj->import_attach) + drm_prime_gem_destroy(obj, shmem->sgt); + +- drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); ++ /* ++ * Prevent memory corruption caused by the use-after-free bug in a ++ * case where shmem user erroneously holds reference to pages while ++ * GEM is freed by leaking the GEM. ++ */ ++ if (drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)) || ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)) || ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count))) ++ return; + + drm_gem_object_release(obj); + kfree(shmem); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (24 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO Dmitry Osipenko + ` (3 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Turn sanity warnings about DRM-SHMEM API misuse into a error conditions +for cases where imported GEM is used when it shouldn't be used. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 0d95d723b90d..7d2fe12bd793 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -409,7 +409,8 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) + struct drm_gem_object *obj = &shmem->base; + int ret; + +- drm_WARN_ON(obj->dev, obj->import_attach); ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return -EINVAL; + + if (refcount_inc_not_zero(&shmem->pages_pin_count)) + return 0; +@@ -872,7 +873,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + +- drm_WARN_ON(obj->dev, obj->import_attach); ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return ERR_PTR(-EINVAL); + + if (drm_WARN_ON(obj->dev, !shmem->pages)) + return ERR_PTR(-ENOMEM); +@@ -909,7 +911,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object + if (shmem->sgt) + return shmem->sgt; + +- drm_WARN_ON(obj->dev, obj->import_attach); ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return ERR_PTR(-EINVAL); + + sgt = drm_gem_shmem_get_sg_table(shmem); + if (IS_ERR(sgt)) +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (25 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically Dmitry Osipenko + ` (2 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Prepare to addition of memory shrinker support by pinning display +framebuffer BO pages in memory while they are in use by display on host. +Shrinker is free to relocate framebuffer BO pages if it doesn't know that +pages are in use, thus pin the pages to disallow shrinker to move them. + +Acked-by: Gerd Hoffmann +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++ + drivers/gpu/drm/virtio/virtgpu_gem.c | 19 +++++++++++++++++++ + drivers/gpu/drm/virtio/virtgpu_plane.c | 17 +++++++++++++++-- + 3 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index bb7d86a0c6a1..83d1e4622292 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -318,6 +318,8 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_work(struct work_struct *work); ++int virtio_gpu_gem_pin(struct virtio_gpu_object *bo); ++void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo); + + /* virtgpu_vq.c */ + int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); +diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c +index 7db48d17ee3a..625c05d625bf 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -294,3 +294,22 @@ void virtio_gpu_array_put_free_work(struct work_struct *work) + } + spin_unlock(&vgdev->obj_free_lock); + } ++ ++int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) ++{ ++ int err; ++ ++ if (virtio_gpu_is_shmem(bo)) { ++ err = drm_gem_shmem_pin(&bo->base); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo) ++{ ++ if (virtio_gpu_is_shmem(bo)) ++ drm_gem_shmem_unpin(&bo->base); ++} +diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c +index a72a2dbda031..162fb8a44d71 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_plane.c ++++ b/drivers/gpu/drm/virtio/virtgpu_plane.c +@@ -248,20 +248,28 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_object *bo; ++ int err; + + if (!new_state->fb) + return 0; + + vgfb = to_virtio_gpu_framebuffer(new_state->fb); + bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); +- if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) ++ ++ err = virtio_gpu_gem_pin(bo); ++ if (err) ++ return err; ++ ++ if (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob) + return 0; + + if (bo->dumb && (plane->state->fb != new_state->fb)) { + vgfb->fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, + 0); +- if (!vgfb->fence) ++ if (!vgfb->fence) { ++ virtio_gpu_gem_unpin(bo); + return -ENOMEM; ++ } + } + + return 0; +@@ -271,15 +279,20 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *state) + { + struct virtio_gpu_framebuffer *vgfb; ++ struct virtio_gpu_object *bo; + + if (!state->fb) + return; + + vgfb = to_virtio_gpu_framebuffer(state->fb); ++ bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); ++ + if (vgfb->fence) { + dma_fence_put(&vgfb->fence->f); + vgfb->fence = NULL; + } ++ ++ virtio_gpu_gem_unpin(bo); + } + + static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (26 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 29/30] drm/virtio: Support shmem shrinking Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker Dmitry Osipenko + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Prepare for addition of memory shrinker support by attaching shmem pages +to host dynamically on first use. Previously the attachment vq command +wasn't fenced and there was no vq kick made in the BO creation code path, +hence the attachment already was happening dynamically, but implicitly. +Making attachment explicitly dynamic will allow to simplify and reuse more +code when shrinker will be added. The virtio_gpu_object_shmem_init() now +works under the held reservation lock, which will be important to have for +shrinker to avoid moving pages while they are in active use by the driver. + +Acked-by: Gerd Hoffmann +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 7 +++ + drivers/gpu/drm/virtio/virtgpu_gem.c | 26 +++++++++ + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 32 +++++++---- + drivers/gpu/drm/virtio/virtgpu_object.c | 73 ++++++++++++++++++++----- + drivers/gpu/drm/virtio/virtgpu_submit.c | 15 ++++- + 5 files changed, 125 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index 83d1e4622292..1837dc7ea9fb 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -92,6 +92,7 @@ struct virtio_gpu_object { + uint32_t hw_res_handle; + bool dumb; + bool created; ++ bool detached; + bool host3d_blob, guest_blob; + uint32_t blob_mem, blob_flags; + +@@ -318,6 +319,8 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_work(struct work_struct *work); ++int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object_array *objs); + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo); + void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo); + +@@ -458,6 +461,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + + bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); + ++int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo); ++ ++int virtio_gpu_reattach_shmem_object(struct virtio_gpu_object *bo); ++ + int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, + uint32_t *resid); + /* virtgpu_prime.c */ +diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c +index 625c05d625bf..97e67064c97e 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -295,6 +295,26 @@ void virtio_gpu_array_put_free_work(struct work_struct *work) + spin_unlock(&vgdev->obj_free_lock); + } + ++int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object_array *objs) ++{ ++ struct virtio_gpu_object *bo; ++ int ret = 0; ++ u32 i; ++ ++ for (i = 0; i < objs->nents; i++) { ++ bo = gem_to_virtio_gpu_obj(objs->objs[i]); ++ ++ if (virtio_gpu_is_shmem(bo) && bo->detached) { ++ ret = virtio_gpu_reattach_shmem_object_locked(bo); ++ if (ret) ++ break; ++ } ++ } ++ ++ return ret; ++} ++ + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) + { + int err; +@@ -303,6 +323,12 @@ int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) + err = drm_gem_shmem_pin(&bo->base); + if (err) + return err; ++ ++ err = virtio_gpu_reattach_shmem_object(bo); ++ if (err) { ++ drm_gem_shmem_unpin(&bo->base); ++ return err; ++ } + } + + return 0; +diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +index e4f76f315550..c7da22006149 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c ++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +@@ -256,6 +256,10 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, + if (ret != 0) + goto err_put_free; + ++ ret = virtio_gpu_array_prepare(vgdev, objs); ++ if (ret) ++ goto err_unlock; ++ + fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); + if (!fence) { + ret = -ENOMEM; +@@ -298,11 +302,25 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, + goto err_put_free; + } + ++ ret = virtio_gpu_array_lock_resv(objs); ++ if (ret != 0) ++ goto err_put_free; ++ ++ ret = virtio_gpu_array_prepare(vgdev, objs); ++ if (ret) ++ goto err_unlock; ++ ++ fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); ++ if (!fence) { ++ ret = -ENOMEM; ++ goto err_unlock; ++ } ++ + if (!vgdev->has_virgl_3d) { + virtio_gpu_cmd_transfer_to_host_2d + (vgdev, offset, + args->box.w, args->box.h, args->box.x, args->box.y, +- objs, NULL); ++ objs, fence); + } else { + virtio_gpu_create_context(dev, file); + +@@ -311,23 +329,13 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, + goto err_put_free; + } + +- ret = virtio_gpu_array_lock_resv(objs); +- if (ret != 0) +- goto err_put_free; +- +- ret = -ENOMEM; +- fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, +- 0); +- if (!fence) +- goto err_unlock; +- + virtio_gpu_cmd_transfer_to_host_3d + (vgdev, + vfpriv ? vfpriv->ctx_id : 0, offset, args->level, + args->stride, args->layer_stride, &args->box, objs, + fence); +- dma_fence_put(&fence->f); + } ++ dma_fence_put(&fence->f); + virtio_gpu_notify(vgdev); + return 0; + +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index e58528c562ef..de347aa3b9a8 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -143,7 +143,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, + struct sg_table *pages; + int si; + +- pages = drm_gem_shmem_get_pages_sgt(&bo->base); ++ pages = drm_gem_shmem_get_pages_sgt_locked(&bo->base); + if (IS_ERR(pages)) + return PTR_ERR(pages); + +@@ -177,6 +177,40 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, + return 0; + } + ++int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; ++ struct virtio_gpu_mem_entry *ents; ++ unsigned int nents; ++ int err; ++ ++ if (!bo->detached) ++ return 0; ++ ++ err = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); ++ if (err) ++ return err; ++ ++ virtio_gpu_object_attach(vgdev, bo, ents, nents); ++ ++ bo->detached = false; ++ ++ return 0; ++} ++ ++int virtio_gpu_reattach_shmem_object(struct virtio_gpu_object *bo) ++{ ++ int ret; ++ ++ ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL); ++ if (ret) ++ return ret; ++ ret = virtio_gpu_reattach_shmem_object_locked(bo); ++ dma_resv_unlock(bo->base.base.resv); ++ ++ return ret; ++} ++ + int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_params *params, + struct virtio_gpu_object **bo_ptr, +@@ -207,45 +241,56 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + + bo->dumb = params->dumb; + +- ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); +- if (ret != 0) +- goto err_put_id; ++ if (bo->blob_mem == VIRTGPU_BLOB_MEM_GUEST) ++ bo->guest_blob = true; + + if (fence) { + ret = -ENOMEM; + objs = virtio_gpu_array_alloc(1); + if (!objs) +- goto err_free_entry; ++ goto err_put_id; + virtio_gpu_array_add_obj(objs, &bo->base.base); + + ret = virtio_gpu_array_lock_resv(objs); + if (ret != 0) + goto err_put_objs; ++ } else { ++ ret = dma_resv_lock(bo->base.base.resv, NULL); ++ if (ret) ++ goto err_put_id; + } + + if (params->blob) { +- if (params->blob_mem == VIRTGPU_BLOB_MEM_GUEST) +- bo->guest_blob = true; ++ ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); ++ if (ret) ++ goto err_unlock_objs; ++ } else { ++ bo->detached = true; ++ } + ++ if (params->blob) + virtio_gpu_cmd_resource_create_blob(vgdev, bo, params, + ents, nents); +- } else if (params->virgl) { ++ else if (params->virgl) + virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, + objs, fence); +- virtio_gpu_object_attach(vgdev, bo, ents, nents); +- } else { ++ else + virtio_gpu_cmd_create_resource(vgdev, bo, params, + objs, fence); +- virtio_gpu_object_attach(vgdev, bo, ents, nents); +- } ++ ++ if (!fence) ++ dma_resv_unlock(bo->base.base.resv); + + *bo_ptr = bo; + return 0; + ++err_unlock_objs: ++ if (fence) ++ virtio_gpu_array_unlock_resv(objs); ++ else ++ dma_resv_unlock(bo->base.base.resv); + err_put_objs: + virtio_gpu_array_put_free(objs); +-err_free_entry: +- kvfree(ents); + err_put_id: + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); + err_put_pages: +diff --git a/drivers/gpu/drm/virtio/virtgpu_submit.c b/drivers/gpu/drm/virtio/virtgpu_submit.c +index 5c514946bbad..6e4ef2593e8f 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_submit.c ++++ b/drivers/gpu/drm/virtio/virtgpu_submit.c +@@ -464,8 +464,19 @@ static void virtio_gpu_install_out_fence_fd(struct virtio_gpu_submit *submit) + + static int virtio_gpu_lock_buflist(struct virtio_gpu_submit *submit) + { +- if (submit->buflist) +- return virtio_gpu_array_lock_resv(submit->buflist); ++ int err; ++ ++ if (submit->buflist) { ++ err = virtio_gpu_array_lock_resv(submit->buflist); ++ if (err) ++ return err; ++ ++ err = virtio_gpu_array_prepare(submit->vgdev, submit->buflist); ++ if (err) { ++ virtio_gpu_array_unlock_resv(submit->buflist); ++ return err; ++ } ++ } + + return 0; + } +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 29/30] drm/virtio: Support shmem shrinking + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (27 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker Dmitry Osipenko + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Support generic drm-shmem memory shrinker and add new madvise IOCTL to +the VirtIO-GPU driver. BO cache manager of Mesa driver will mark BOs as +"don't need" using the new IOCTL to let shrinker purge the marked BOs on +OOM, the shrinker will also evict unpurgeable shmem BOs from memory if +guest supports SWAP file or partition. + +Link: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15278 +Acked-by: Gerd Hoffmann +Signed-off-by: Daniel Almeida +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 13 +++++- + drivers/gpu/drm/virtio/virtgpu_gem.c | 48 +++++++++++++++++-- + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 25 ++++++++++ + drivers/gpu/drm/virtio/virtgpu_kms.c | 8 ++++ + drivers/gpu/drm/virtio/virtgpu_object.c | 61 +++++++++++++++++++++++++ + drivers/gpu/drm/virtio/virtgpu_vq.c | 40 ++++++++++++++++ + include/uapi/drm/virtgpu_drm.h | 14 ++++++ + 7 files changed, 204 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index 1837dc7ea9fb..37188c00e161 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -283,7 +283,7 @@ struct virtio_gpu_fpriv { + }; + + /* virtgpu_ioctl.c */ +-#define DRM_VIRTIO_NUM_IOCTLS 12 ++#define DRM_VIRTIO_NUM_IOCTLS 13 + extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; + void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file); + +@@ -321,6 +321,8 @@ void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + void virtio_gpu_array_put_free_work(struct work_struct *work); + int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs); ++int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo); ++int virtio_gpu_gem_madvise(struct virtio_gpu_object *obj, int madv); + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo); + void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo); + +@@ -334,6 +336,8 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, + struct virtio_gpu_fence *fence); + void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo); ++int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *bo); + void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, + uint64_t offset, + uint32_t width, uint32_t height, +@@ -354,6 +358,9 @@ void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *obj, + struct virtio_gpu_mem_entry *ents, + unsigned int nents); ++void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *obj, ++ struct virtio_gpu_fence *fence); + void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, + struct virtio_gpu_output *output); + int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev); +@@ -497,4 +504,8 @@ void virtio_gpu_vram_unmap_dma_buf(struct device *dev, + int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); + ++/* virtgpu_gem_shrinker.c */ ++int virtio_gpu_gem_shrinker_init(struct virtio_gpu_device *vgdev); ++void virtio_gpu_gem_shrinker_fini(struct virtio_gpu_device *vgdev); ++ + #endif +diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c +index 97e67064c97e..68d27ae582ba 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -147,10 +147,20 @@ void virtio_gpu_gem_object_close(struct drm_gem_object *obj, + struct virtio_gpu_device *vgdev = obj->dev->dev_private; + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; + struct virtio_gpu_object_array *objs; ++ struct virtio_gpu_object *bo; + + if (!vgdev->has_virgl_3d) + return; + ++ bo = gem_to_virtio_gpu_obj(obj); ++ ++ /* ++ * Purged BO was already detached and released, the resource ID ++ * is invalid by now. ++ */ ++ if (!virtio_gpu_gem_madvise(bo, VIRTGPU_MADV_WILLNEED)) ++ return; ++ + objs = virtio_gpu_array_alloc(1); + if (!objs) + return; +@@ -305,16 +315,46 @@ int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, + for (i = 0; i < objs->nents; i++) { + bo = gem_to_virtio_gpu_obj(objs->objs[i]); + +- if (virtio_gpu_is_shmem(bo) && bo->detached) { +- ret = virtio_gpu_reattach_shmem_object_locked(bo); +- if (ret) +- break; ++ if (virtio_gpu_is_shmem(bo)) { ++ if (bo->base.madv) ++ return -EINVAL; ++ ++ if (bo->detached) { ++ ret = virtio_gpu_reattach_shmem_object_locked(bo); ++ if (ret) ++ break; ++ } + } + } + + return ret; + } + ++int virtio_gpu_gem_madvise(struct virtio_gpu_object *bo, int madv) ++{ ++ if (virtio_gpu_is_shmem(bo)) ++ return drm_gem_shmem_object_madvise(&bo->base.base, madv); ++ ++ return 1; ++} ++ ++int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; ++ int err; ++ ++ if (bo->created) { ++ err = virtio_gpu_cmd_release_resource(vgdev, bo); ++ if (err) ++ return err; ++ ++ virtio_gpu_notify(vgdev); ++ bo->created = false; ++ } ++ ++ return 0; ++} ++ + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) + { + int err; +diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +index c7da22006149..a42799146090 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c ++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +@@ -701,6 +701,28 @@ static int virtio_gpu_context_init_ioctl(struct drm_device *dev, + return ret; + } + ++static int virtio_gpu_madvise_ioctl(struct drm_device *dev, ++ void *data, ++ struct drm_file *file) ++{ ++ struct drm_virtgpu_madvise *args = data; ++ struct virtio_gpu_object *bo; ++ struct drm_gem_object *obj; ++ ++ if (args->madv > VIRTGPU_MADV_DONTNEED) ++ return -EOPNOTSUPP; ++ ++ obj = drm_gem_object_lookup(file, args->bo_handle); ++ if (!obj) ++ return -ENOENT; ++ ++ bo = gem_to_virtio_gpu_obj(obj); ++ args->retained = virtio_gpu_gem_madvise(bo, args->madv); ++ drm_gem_object_put(obj); ++ ++ return 0; ++} ++ + struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { + DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl, + DRM_RENDER_ALLOW), +@@ -740,4 +762,7 @@ struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { + + DRM_IOCTL_DEF_DRV(VIRTGPU_CONTEXT_INIT, virtio_gpu_context_init_ioctl, + DRM_RENDER_ALLOW), ++ ++ DRM_IOCTL_DEF_DRV(VIRTGPU_MADVISE, virtio_gpu_madvise_ioctl, ++ DRM_RENDER_ALLOW), + }; +diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c +index 5a3b5aaed1f3..43e237082cec 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_kms.c ++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c +@@ -245,6 +245,12 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) + goto err_scanouts; + } + ++ ret = drmm_gem_shmem_init(dev); ++ if (ret) { ++ DRM_ERROR("shmem init failed\n"); ++ goto err_modeset; ++ } ++ + virtio_device_ready(vgdev->vdev); + + if (num_capsets) +@@ -259,6 +265,8 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) + } + return 0; + ++err_modeset: ++ virtio_gpu_modeset_fini(vgdev); + err_scanouts: + virtio_gpu_free_vbufs(vgdev); + err_vbufs: +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index de347aa3b9a8..86888c1ae5d4 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -98,6 +98,60 @@ static void virtio_gpu_free_object(struct drm_gem_object *obj) + virtio_gpu_cleanup_object(bo); + } + ++static int virtio_gpu_detach_object_fenced(struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; ++ struct virtio_gpu_fence *fence; ++ ++ if (bo->detached) ++ return 0; ++ ++ fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); ++ if (!fence) ++ return -ENOMEM; ++ ++ virtio_gpu_object_detach(vgdev, bo, fence); ++ virtio_gpu_notify(vgdev); ++ ++ dma_fence_wait(&fence->f, false); ++ dma_fence_put(&fence->f); ++ ++ bo->detached = true; ++ ++ return 0; ++} ++ ++static int virtio_gpu_shmem_evict(struct drm_gem_object *obj) ++{ ++ struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); ++ int err; ++ ++ /* blob is not movable, it's impossible to detach it from host */ ++ if (bo->blob_mem) ++ return -EBUSY; ++ ++ /* ++ * At first tell host to stop using guest's memory to ensure that ++ * host won't touch the released guest's memory once it's gone. ++ */ ++ err = virtio_gpu_detach_object_fenced(bo); ++ if (err) ++ return err; ++ ++ if (drm_gem_shmem_is_purgeable(&bo->base)) { ++ err = virtio_gpu_gem_host_mem_release(bo); ++ if (err) ++ return err; ++ ++ drm_gem_shmem_purge_locked(&bo->base); ++ } else { ++ bo->base.pages_mark_dirty_on_put = 1; ++ drm_gem_shmem_evict_locked(&bo->base); ++ } ++ ++ return 0; ++} ++ + static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = { + .free = virtio_gpu_free_object, + .open = virtio_gpu_gem_object_open, +@@ -111,6 +165,7 @@ static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = { + .vunmap = drm_gem_shmem_object_vunmap, + .mmap = drm_gem_shmem_object_mmap, + .vm_ops = &drm_gem_shmem_vm_ops, ++ .evict = virtio_gpu_shmem_evict, + }; + + bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo) +@@ -187,6 +242,10 @@ int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo) + if (!bo->detached) + return 0; + ++ err = drm_gem_shmem_swapin_locked(&bo->base); ++ if (err) ++ return err; ++ + err = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); + if (err) + return err; +@@ -240,6 +299,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + goto err_put_pages; + + bo->dumb = params->dumb; ++ bo->blob_mem = params->blob_mem; ++ bo->blob_flags = params->blob_flags; + + if (bo->blob_mem == VIRTGPU_BLOB_MEM_GUEST) + bo->guest_blob = true; +diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c +index b1a00c0c25a7..14ab470f413a 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_vq.c ++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c +@@ -545,6 +545,21 @@ void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, + virtio_gpu_cleanup_object(bo); + } + ++int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_resource_unref *cmd_p; ++ struct virtio_gpu_vbuffer *vbuf; ++ ++ cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); ++ memset(cmd_p, 0, sizeof(*cmd_p)); ++ ++ cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_UNREF); ++ cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); ++ ++ return virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); ++} ++ + void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, uint32_t resource_id, + uint32_t width, uint32_t height, +@@ -645,6 +660,23 @@ virtio_gpu_cmd_resource_attach_backing(struct virtio_gpu_device *vgdev, + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + } + ++static void ++virtio_gpu_cmd_resource_detach_backing(struct virtio_gpu_device *vgdev, ++ u32 resource_id, ++ struct virtio_gpu_fence *fence) ++{ ++ struct virtio_gpu_resource_attach_backing *cmd_p; ++ struct virtio_gpu_vbuffer *vbuf; ++ ++ cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); ++ memset(cmd_p, 0, sizeof(*cmd_p)); ++ ++ cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING); ++ cmd_p->resource_id = cpu_to_le32(resource_id); ++ ++ virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); ++} ++ + static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, + struct virtio_gpu_vbuffer *vbuf) + { +@@ -1107,6 +1139,14 @@ void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, + ents, nents, NULL); + } + ++void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *obj, ++ struct virtio_gpu_fence *fence) ++{ ++ virtio_gpu_cmd_resource_detach_backing(vgdev, obj->hw_res_handle, ++ fence); ++} ++ + void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, + struct virtio_gpu_output *output) + { +diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h +index c2ce71987e9b..78255060bc9a 100644 +--- a/include/uapi/drm/virtgpu_drm.h ++++ b/include/uapi/drm/virtgpu_drm.h +@@ -48,6 +48,7 @@ extern "C" { + #define DRM_VIRTGPU_GET_CAPS 0x09 + #define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a + #define DRM_VIRTGPU_CONTEXT_INIT 0x0b ++#define DRM_VIRTGPU_MADVISE 0x0c + + #define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01 + #define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02 +@@ -213,6 +214,15 @@ struct drm_virtgpu_context_init { + __u64 ctx_set_params; + }; + ++#define VIRTGPU_MADV_WILLNEED 0 ++#define VIRTGPU_MADV_DONTNEED 1 ++struct drm_virtgpu_madvise { ++ __u32 bo_handle; ++ __u32 retained; /* out, non-zero if BO can be used */ ++ __u32 madv; ++ __u32 pad; ++}; ++ + /* + * Event code that's given when VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK is in + * effect. The event size is sizeof(drm_event), since there is no additional +@@ -263,6 +273,10 @@ struct drm_virtgpu_context_init { + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_CONTEXT_INIT, \ + struct drm_virtgpu_context_init) + ++#define DRM_IOCTL_VIRTGPU_MADVISE \ ++ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MADVISE, \ ++ struct drm_virtgpu_madvise) ++ + #if defined(__cplusplus) + } + #endif +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (28 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 29/30] drm/virtio: Support shmem shrinking Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Replace Panfrost's custom memory shrinker with a common drm-shmem +memory shrinker. + +Co-developed-by: Boris Brezillon +Signed-off-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 4 +- + drivers/gpu/drm/panfrost/Makefile | 1 - + drivers/gpu/drm/panfrost/panfrost_device.h | 4 - + drivers/gpu/drm/panfrost/panfrost_drv.c | 29 ++-- + drivers/gpu/drm/panfrost/panfrost_gem.c | 60 ++++---- + drivers/gpu/drm/panfrost/panfrost_gem.h | 9 -- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 140 ------------------ + drivers/gpu/drm/panfrost/panfrost_job.c | 18 ++- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 24 ++- + include/drm/drm_gem_shmem_helper.h | 7 - + 10 files changed, 83 insertions(+), 213 deletions(-) + delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 7d2fe12bd793..56e88378079b 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -89,8 +89,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private) + if (ret) + goto err_release; + +- INIT_LIST_HEAD(&shmem->madv_list); +- + if (!private) { + /* + * Our buffers are kept pinned, so allocating them +@@ -619,6 +617,8 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + ++ drm_WARN_ON_ONCE(obj->dev, !drm_gem_shmem_is_purgeable(shmem)); ++ + drm_gem_shmem_shrinker_put_pages_locked(shmem); + drm_gem_free_mmap_offset(obj); + +diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile +index 2c01c1e7523e..f2cb1ab0a32d 100644 +--- a/drivers/gpu/drm/panfrost/Makefile ++++ b/drivers/gpu/drm/panfrost/Makefile +@@ -5,7 +5,6 @@ panfrost-y := \ + panfrost_device.o \ + panfrost_devfreq.o \ + panfrost_gem.o \ +- panfrost_gem_shrinker.o \ + panfrost_gpu.o \ + panfrost_job.o \ + panfrost_mmu.o \ +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index 62f7e3527385..cea6df9cd650 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -140,10 +140,6 @@ struct panfrost_device { + atomic_t pending; + } reset; + +- struct mutex shrinker_lock; +- struct list_head shrinker_list; +- struct shrinker *shrinker; +- + struct panfrost_devfreq pfdevfreq; + + struct { +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index a15d62f19afb..5c730d15a24d 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -171,7 +171,6 @@ panfrost_lookup_bos(struct drm_device *dev, + break; + } + +- atomic_inc(&bo->gpu_usecount); + job->mappings[i] = mapping; + } + +@@ -397,7 +396,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + { + struct panfrost_file_priv *priv = file_priv->driver_priv; + struct drm_panfrost_madvise *args = data; +- struct panfrost_device *pfdev = dev->dev_private; + struct drm_gem_object *gem_obj; + struct panfrost_gem_object *bo; + int ret = 0; +@@ -410,11 +408,15 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + + bo = to_panfrost_bo(gem_obj); + ++ if (bo->is_heap) { ++ args->retained = 1; ++ goto out_put_object; ++ } ++ + ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL); + if (ret) + goto out_put_object; + +- mutex_lock(&pfdev->shrinker_lock); + mutex_lock(&bo->mappings.lock); + if (args->madv == PANFROST_MADV_DONTNEED) { + struct panfrost_gem_mapping *first; +@@ -440,17 +442,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + + args->retained = drm_gem_shmem_madvise_locked(&bo->base, args->madv); + +- if (args->retained) { +- if (args->madv == PANFROST_MADV_DONTNEED) +- list_move_tail(&bo->base.madv_list, +- &pfdev->shrinker_list); +- else if (args->madv == PANFROST_MADV_WILLNEED) +- list_del_init(&bo->base.madv_list); +- } +- + out_unlock_mappings: + mutex_unlock(&bo->mappings.lock); +- mutex_unlock(&pfdev->shrinker_lock); + dma_resv_unlock(bo->base.base.resv); + out_put_object: + drm_gem_object_put(gem_obj); +@@ -635,9 +628,6 @@ static int panfrost_probe(struct platform_device *pdev) + ddev->dev_private = pfdev; + pfdev->ddev = ddev; + +- mutex_init(&pfdev->shrinker_lock); +- INIT_LIST_HEAD(&pfdev->shrinker_list); +- + err = panfrost_device_init(pfdev); + if (err) { + if (err != -EPROBE_DEFER) +@@ -659,13 +649,13 @@ static int panfrost_probe(struct platform_device *pdev) + if (err < 0) + goto err_out1; + +- err = panfrost_gem_shrinker_init(ddev); +- if (err) +- goto err_out2; ++ err = drmm_gem_shmem_init(ddev); ++ if (err < 0) ++ goto err_unregister_dev; + + return 0; + +-err_out2: ++err_unregister_dev: + drm_dev_unregister(ddev); + err_out1: + pm_runtime_disable(pfdev->dev); +@@ -682,7 +672,6 @@ static void panfrost_remove(struct platform_device *pdev) + struct drm_device *ddev = pfdev->ddev; + + drm_dev_unregister(ddev); +- panfrost_gem_shrinker_cleanup(ddev); + + pm_runtime_get_sync(pfdev->dev); + pm_runtime_disable(pfdev->dev); +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index 8c26b7e41b95..05eb5a89c4ed 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -17,17 +17,6 @@ + static void panfrost_gem_free_object(struct drm_gem_object *obj) + { + struct panfrost_gem_object *bo = to_panfrost_bo(obj); +- struct panfrost_device *pfdev = obj->dev->dev_private; +- +- /* +- * Make sure the BO is no longer inserted in the shrinker list before +- * taking care of the destruction itself. If we don't do that we have a +- * race condition between this function and what's done in +- * panfrost_gem_shrinker_scan(). +- */ +- mutex_lock(&pfdev->shrinker_lock); +- list_del_init(&bo->base.madv_list); +- mutex_unlock(&pfdev->shrinker_lock); + + /* + * If we still have mappings attached to the BO, there's a problem in +@@ -57,26 +46,23 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, + return mapping; + } + +-static void +-panfrost_gem_teardown_mapping(struct panfrost_gem_mapping *mapping) ++static void panfrost_gem_mapping_release(struct kref *kref) + { ++ struct panfrost_gem_mapping *mapping = ++ container_of(kref, struct panfrost_gem_mapping, refcount); ++ struct panfrost_gem_object *bo = mapping->obj; ++ struct panfrost_device *pfdev = bo->base.base.dev->dev_private; ++ ++ /* Shrinker may purge the mapping at the same time. */ ++ dma_resv_lock(mapping->obj->base.base.resv, NULL); + if (mapping->active) + panfrost_mmu_unmap(mapping); ++ dma_resv_unlock(mapping->obj->base.base.resv); + + spin_lock(&mapping->mmu->mm_lock); + if (drm_mm_node_allocated(&mapping->mmnode)) + drm_mm_remove_node(&mapping->mmnode); + spin_unlock(&mapping->mmu->mm_lock); +-} +- +-static void panfrost_gem_mapping_release(struct kref *kref) +-{ +- struct panfrost_gem_mapping *mapping = +- container_of(kref, struct panfrost_gem_mapping, refcount); +- struct panfrost_gem_object *bo = mapping->obj; +- struct panfrost_device *pfdev = bo->base.base.dev->dev_private; +- +- panfrost_gem_teardown_mapping(mapping); + + /* On heap BOs, release the sgts created in the fault handler path. */ + if (bo->sgts) { +@@ -117,12 +103,14 @@ void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping) + kref_put(&mapping->refcount, panfrost_gem_mapping_release); + } + +-void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo) ++void panfrost_gem_evict_mappings_locked(struct panfrost_gem_object *bo) + { + struct panfrost_gem_mapping *mapping; + +- list_for_each_entry(mapping, &bo->mappings.list, node) +- panfrost_gem_teardown_mapping(mapping); ++ list_for_each_entry(mapping, &bo->mappings.list, node) { ++ if (mapping->active) ++ panfrost_mmu_unmap(mapping); ++ } + } + + int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) +@@ -251,6 +239,25 @@ static size_t panfrost_gem_rss(struct drm_gem_object *obj) + return 0; + } + ++static int panfrost_shmem_evict(struct drm_gem_object *obj) ++{ ++ struct panfrost_gem_object *bo = to_panfrost_bo(obj); ++ ++ if (!drm_gem_shmem_is_purgeable(&bo->base)) ++ return -EBUSY; ++ ++ if (!mutex_trylock(&bo->mappings.lock)) ++ return -EBUSY; ++ ++ panfrost_gem_evict_mappings_locked(bo); ++ ++ drm_gem_shmem_purge_locked(&bo->base); ++ ++ mutex_unlock(&bo->mappings.lock); ++ ++ return 0; ++} ++ + static const struct drm_gem_object_funcs panfrost_gem_funcs = { + .free = panfrost_gem_free_object, + .open = panfrost_gem_open, +@@ -265,6 +272,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = { + .status = panfrost_gem_status, + .rss = panfrost_gem_rss, + .vm_ops = &drm_gem_shmem_vm_ops, ++ .evict = panfrost_shmem_evict, + }; + + /** +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h +index 7516b7ecf7fe..8ddc2d310d29 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.h ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.h +@@ -30,12 +30,6 @@ struct panfrost_gem_object { + struct mutex lock; + } mappings; + +- /* +- * Count the number of jobs referencing this BO so we don't let the +- * shrinker reclaim this object prematurely. +- */ +- atomic_t gpu_usecount; +- + /* + * Object chunk size currently mapped onto physical memory + */ +@@ -86,7 +80,4 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, + void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); + void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); + +-int panfrost_gem_shrinker_init(struct drm_device *dev); +-void panfrost_gem_shrinker_cleanup(struct drm_device *dev); +- + #endif /* __PANFROST_GEM_H__ */ +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +deleted file mode 100644 +index 7b4deba803ed..000000000000 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ /dev/null +@@ -1,140 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* Copyright (C) 2019 Arm Ltd. +- * +- * Based on msm_gem_freedreno.c: +- * Copyright (C) 2016 Red Hat +- * Author: Rob Clark +- */ +- +-#include +- +-#include +-#include +- +-#include "panfrost_device.h" +-#include "panfrost_gem.h" +-#include "panfrost_mmu.h" +- +-static bool panfrost_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) +-{ +- return (shmem->madv > 0) && +- !refcount_read(&shmem->pages_pin_count) && shmem->sgt && +- !shmem->base.dma_buf && !shmem->base.import_attach; +-} +- +-static unsigned long +-panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) +-{ +- struct panfrost_device *pfdev = shrinker->private_data; +- struct drm_gem_shmem_object *shmem; +- unsigned long count = 0; +- +- if (!mutex_trylock(&pfdev->shrinker_lock)) +- return 0; +- +- list_for_each_entry(shmem, &pfdev->shrinker_list, madv_list) { +- if (panfrost_gem_shmem_is_purgeable(shmem)) +- count += shmem->base.size >> PAGE_SHIFT; +- } +- +- mutex_unlock(&pfdev->shrinker_lock); +- +- return count; +-} +- +-static bool panfrost_gem_purge(struct drm_gem_object *obj) +-{ +- struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); +- struct panfrost_gem_object *bo = to_panfrost_bo(obj); +- bool ret = false; +- +- if (atomic_read(&bo->gpu_usecount)) +- return false; +- +- if (!mutex_trylock(&bo->mappings.lock)) +- return false; +- +- if (!dma_resv_trylock(shmem->base.resv)) +- goto unlock_mappings; +- +- /* BO might have become unpurgeable if the last pages_use_count ref +- * was dropped, but the BO hasn't been destroyed yet. +- */ +- if (!panfrost_gem_shmem_is_purgeable(shmem)) +- goto unlock_mappings; +- +- panfrost_gem_teardown_mappings_locked(bo); +- drm_gem_shmem_purge_locked(&bo->base); +- ret = true; +- +- dma_resv_unlock(shmem->base.resv); +- +-unlock_mappings: +- mutex_unlock(&bo->mappings.lock); +- return ret; +-} +- +-static unsigned long +-panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) +-{ +- struct panfrost_device *pfdev = shrinker->private_data; +- struct drm_gem_shmem_object *shmem, *tmp; +- unsigned long freed = 0; +- +- if (!mutex_trylock(&pfdev->shrinker_lock)) +- return SHRINK_STOP; +- +- list_for_each_entry_safe(shmem, tmp, &pfdev->shrinker_list, madv_list) { +- if (freed >= sc->nr_to_scan) +- break; +- if (panfrost_gem_shmem_is_purgeable(shmem) && +- panfrost_gem_purge(&shmem->base)) { +- freed += shmem->base.size >> PAGE_SHIFT; +- list_del_init(&shmem->madv_list); +- } +- } +- +- mutex_unlock(&pfdev->shrinker_lock); +- +- if (freed > 0) +- pr_info_ratelimited("Purging %lu bytes\n", freed << PAGE_SHIFT); +- +- return freed; +-} +- +-/** +- * panfrost_gem_shrinker_init - Initialize panfrost shrinker +- * @dev: DRM device +- * +- * This function registers and sets up the panfrost shrinker. +- */ +-int panfrost_gem_shrinker_init(struct drm_device *dev) +-{ +- struct panfrost_device *pfdev = dev->dev_private; +- +- pfdev->shrinker = shrinker_alloc(0, "drm-panfrost"); +- if (!pfdev->shrinker) +- return -ENOMEM; +- +- pfdev->shrinker->count_objects = panfrost_gem_shrinker_count; +- pfdev->shrinker->scan_objects = panfrost_gem_shrinker_scan; +- pfdev->shrinker->private_data = pfdev; +- +- shrinker_register(pfdev->shrinker); +- +- return 0; +-} +- +-/** +- * panfrost_gem_shrinker_cleanup - Clean up panfrost shrinker +- * @dev: DRM device +- * +- * This function unregisters the panfrost shrinker. +- */ +-void panfrost_gem_shrinker_cleanup(struct drm_device *dev) +-{ +- struct panfrost_device *pfdev = dev->dev_private; +- +- if (pfdev->shrinker) +- shrinker_free(pfdev->shrinker); +-} +diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c +index 0c2dbf6ef2a5..9e26cb013191 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_job.c ++++ b/drivers/gpu/drm/panfrost/panfrost_job.c +@@ -289,6 +289,19 @@ static void panfrost_attach_object_fences(struct drm_gem_object **bos, + dma_resv_add_fence(bos[i]->resv, fence, DMA_RESV_USAGE_WRITE); + } + ++static int panfrost_objects_prepare(struct drm_gem_object **bos, int bo_count) ++{ ++ struct panfrost_gem_object *bo; ++ int ret = 0; ++ ++ while (!ret && bo_count--) { ++ bo = to_panfrost_bo(bos[bo_count]); ++ ret = bo->base.madv != PANFROST_MADV_WILLNEED ? -EINVAL : 0; ++ } ++ ++ return ret; ++} ++ + int panfrost_job_push(struct panfrost_job *job) + { + struct panfrost_device *pfdev = job->pfdev; +@@ -300,6 +313,10 @@ int panfrost_job_push(struct panfrost_job *job) + if (ret) + return ret; + ++ ret = panfrost_objects_prepare(job->bos, job->bo_count); ++ if (ret) ++ goto unlock; ++ + mutex_lock(&pfdev->sched_lock); + drm_sched_job_arm(&job->base); + +@@ -341,7 +358,6 @@ static void panfrost_job_cleanup(struct kref *ref) + if (!job->mappings[i]) + break; + +- atomic_dec(&job->mappings[i]->obj->gpu_usecount); + panfrost_gem_mapping_put(job->mappings[i]); + } + kvfree(job->mappings); +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 4a0b4bf03f1a..22e18f7986e7 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -328,6 +328,7 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) + struct panfrost_device *pfdev = to_panfrost_device(obj->dev); + struct sg_table *sgt; + int prot = IOMMU_READ | IOMMU_WRITE; ++ int ret = 0; + + if (WARN_ON(mapping->active)) + return 0; +@@ -335,15 +336,32 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) + if (bo->noexec) + prot |= IOMMU_NOEXEC; + ++ if (!obj->import_attach) { ++ /* ++ * Don't allow shrinker to move pages while pages are mapped. ++ * It's fine to move pages afterwards because shrinker will ++ * take care of unmapping pages during eviction. ++ */ ++ ret = drm_gem_shmem_pin(shmem); ++ if (ret) ++ return ret; ++ } ++ + sgt = drm_gem_shmem_get_pages_sgt(shmem); +- if (WARN_ON(IS_ERR(sgt))) +- return PTR_ERR(sgt); ++ if (WARN_ON(IS_ERR(sgt))) { ++ ret = PTR_ERR(sgt); ++ goto unpin; ++ } + + mmu_map_sg(pfdev, mapping->mmu, mapping->mmnode.start << PAGE_SHIFT, + prot, sgt); + mapping->active = true; + +- return 0; ++unpin: ++ if (!obj->import_attach) ++ drm_gem_shmem_unpin(shmem); ++ ++ return ret; + } + + void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping) +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 167f00f089de..9c6bb00260fc 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -61,13 +61,6 @@ struct drm_gem_shmem_object { + */ + int madv; + +- /** +- * @madv_list: List entry for madvise tracking +- * +- * Typically used by drivers to track purgeable objects +- */ +- struct list_head madv_list; +- + /** + * @sgt: Scatter/gather table for imported PRIME buffers + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +end of thread, other threads:[~2024-01-05 18:47 UTC | newest] + +Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed) +-- links below jump to the message on this page -- +2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 19/30] drm/virtio: " Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 20/30] drm/v3d: " Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 21/30] drm/shmem-helper: Change sgt allocation policy Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 29/30] drm/virtio: Support shmem shrinking Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker Dmitry Osipenko +This is a public inbox, see mirroring instructions +for how to clone and mirror all data and code used for this inbox; +as well as URLs for NNTP newsgroup(s). diff --git a/projects/Rockchip/packages/linux/patches/RK3399/000-rk3399-dts.patch b/projects/Rockchip/packages/linux/patches/RK3399/000-rk3399-dts.patch index 5c4014b2a8..c637b023a3 100644 --- a/projects/Rockchip/packages/linux/patches/RK3399/000-rk3399-dts.patch +++ b/projects/Rockchip/packages/linux/patches/RK3399/000-rk3399-dts.patch @@ -1,6 +1,6 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/Makefile linux/arch/arm64/boot/dts/rockchip/Makefile ---- linux.orig/arch/arm64/boot/dts/rockchip/Makefile 2024-01-09 14:07:11.858381650 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/Makefile 2024-01-09 18:09:58.589953944 +0000 +--- linux.orig/arch/arm64/boot/dts/rockchip/Makefile 2024-01-23 23:55:32.434476392 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/Makefile 2024-01-25 01:21:59.078794990 +0000 @@ -29,6 +29,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-li dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb @@ -11,8 +11,8 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/Makefile linux/arch/arm64/boo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-ficus.dtb diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-anbernic-rg552.dts linux/arch/arm64/boot/dts/rockchip/rk3399-anbernic-rg552.dts --- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-anbernic-rg552.dts 1970-01-01 00:00:00.000000000 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3399-anbernic-rg552.dts 2024-01-09 18:09:58.589953944 +0000 -@@ -0,0 +1,1336 @@ ++++ linux/arch/arm64/boot/dts/rockchip/rk3399-anbernic-rg552.dts 2024-01-25 01:22:30.031520037 +0000 +@@ -0,0 +1,1325 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. @@ -490,17 +490,6 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-anbernic-rg552.dts lin + vin-supply = <&vcc12v_dcin>; + }; + -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm2 0 25000 1>; -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1700000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ + vcc5v5_lcd: vcc5v5-lcd { + compatible = "regulator-fixed"; + enable-active-high; diff --git a/projects/Rockchip/packages/linux/patches/RK3399/001-rk3399-opp.patch b/projects/Rockchip/packages/linux/patches/RK3399/001-rk3399-opp.patch index becfaa8b5c..012b7ca51d 100644 --- a/projects/Rockchip/packages/linux/patches/RK3399/001-rk3399-opp.patch +++ b/projects/Rockchip/packages/linux/patches/RK3399/001-rk3399-opp.patch @@ -1,7 +1,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi linux/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi ---- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi 2024-01-02 16:20:12.770155149 +0000 -+++ linux/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi 2024-01-02 21:04:45.168352345 +0000 -@@ -9,34 +9,30 @@ +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi 2024-01-31 00:19:09.560493706 +0000 ++++ linux/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi 2024-01-31 00:23:30.222617860 +0000 +@@ -9,34 +9,35 @@ opp-shared; opp00 { @@ -42,10 +42,15 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi linux/arc + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <1200000>; + }; ++ opp06 { ++ opp-hz = /bits/ 64 <1704000000>; ++ opp-microvolt = <1225000>; ++ turbo-mode; ++ }; }; cluster1_opp: opp-table-1 { -@@ -44,40 +40,32 @@ +@@ -44,42 +45,39 @@ opp-shared; opp00 { @@ -93,8 +98,15 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi linux/arc + opp-hz = /bits/ 64 <2088000000>; opp-microvolt = <1250000>; }; ++ opp07 { ++ opp-hz = /bits/ 64 <2208000000>; ++ opp-microvolt = <1350000>; ++ turbo-mode; ++ }; }; -@@ -90,46 +78,30 @@ + + gpu_opp_table: opp-table-2 { +@@ -90,44 +88,25 @@ opp-microvolt = <800000>; }; opp01 { @@ -122,6 +134,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi linux/arc + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = <1150000>; + }; ++ }; dmc_opp_table: opp-table-3 { @@ -132,19 +145,16 @@ diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi linux/arc - opp-microvolt = <900000>; - }; - opp01 { - opp-hz = /bits/ 64 <666000000>; - opp-microvolt = <900000>; - }; +- opp-hz = /bits/ 64 <666000000>; +- opp-microvolt = <900000>; +- }; - opp02 { - opp-hz = /bits/ 64 <800000000>; -+ opp01 { -+ opp-hz = /bits/ 64 <856000000>; - opp-microvolt = <900000>; - }; +- opp-microvolt = <900000>; +- }; - opp03 { - opp-hz = /bits/ 64 <928000000>; -- opp-microvolt = <925000>; -- }; ++ opp-hz = /bits/ 64 <933000000>; + opp-microvolt = <925000>; + }; }; - }; - diff --git a/projects/Rockchip/packages/linux/patches/RK3399/100-panfrost-memory-shrinker.patch b/projects/Rockchip/packages/linux/patches/RK3399/100-panfrost-memory-shrinker.patch new file mode 100644 index 0000000000..eab5999678 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RK3399/100-panfrost-memory-shrinker.patch @@ -0,0 +1,5235 @@ +* [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers +@ 2024-01-05 18:45 Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko + ` (29 more replies) + 0 siblings, 30 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +This series: + + 1. Adds common drm-shmem memory shrinker + 2. Moves drm-shmem drivers to new SGT usage policy + 3. Enables shrinker for VirtIO-GPU driver + 4. Switches Panfrost driver to the common shrinker + 5. Fixes bugs and improves/refactors drm-shmem code + +Mesa: https://gitlab.freedesktop.org/digetx/mesa/-/commits/virgl-madvise +IGT: https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/virtio-madvise + https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/panfrost-madvise + +Changelog: + +v19:- Addressed v18 review comments from Boris Brezillon: + + - Improved bisectablity of Panfrost and drm-shmem patches by + fixing iterim warning splats related to shrinker changes. + + - Improved commit messages + + - Reworked Lima patch to avoid adding `put_pages` flag + + - Reworked Panfrost patch that switches driver to explicit + get/put pages by moving drm_gem_shmem_put_pages() into + gem_mapping_release() instead of gem_free_object(). + + - Updated Panfrost patch that switches driver to generic shrinker + with more comments and minor imporovemnts. + + - Added new Panfrost patch from Boris that fixes handling of + a partially mapped heap BOs. + + - Added link to the related Mesa MR to the commit msg of the patch + that adds new DRM_VIRTGPU_MADVISE ioctl, like was requested by + Gurchetan Singh. + + - Added ackes/r-b from Boris Brezillon and Maxime Ripard + + - New patches in v19: + + drm/gem: Document locking rule of vmap and evict callbacks + drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + + - Factored out couple code changes into these new separate patches: + + drm/shmem-helper: Avoid lockdep warning when pages are released + drm/shmem-helper: Turn warnings about imported GEM into errors + +v18:- Added new pathes that change sgt allocation policy. Previously once + sgt was allocated, it exsited till GEM was freed. Now sgt is destroyed + once pages are unpinned and drivers have to manage the pages' pinning + refcounting by themselves using get/put() and pin/unpin() pages. + This removes pages refcounting ambiguity from the drm-shmem core. + + - Dropped patch that changed drm_gem_shmem_vmap_locked() error handling, + like was requested by Boris Brezillon. + + - Added new patches that make minor improvements: + + - Optimize unlocked get_pages_sgt() + - Don't free refcounted GEM + + - Dropped t-b from the Panfrost shrinker patch that was given for older + patch version since code changed with the new sgt allocation policy. + +v17:- Dropped patches that added new drm-shmem sgt flags, fixing dma-buf UAF + in drm-prime error code path and preventing invalid page_count when GEM + is freed. Will revist them later on and then factor them out into a + seprate patchset. + + - Dropped patches that replaced drm_gem_shmem_free() with + drm_gem_object_put(), they not needed anymore after changing + drm_gem_shmem_free() to not touch reservation lock. + + - Addressed review comments from Boris Brezillon: + + - Added new patch to clean up error unwinding in + drm_gem_shmem_vmap_locked() + + - Added new __drm_gem_shmem_put_pages() to let the callers + to assert the held reservation lock themselves + + - Moved replacement of shmem->pages check with refcount_read() + in drm_gem_shmem_free() to the shrinker addition patch + + - Improved commit message of the vmap_use_count patch + + - Added r-bs from Boris Brezillon that he gave to v16 + +v16:- Added more comments to the code for the new drm-shmem flags + + - Added r-bs from Boris Brezillon + + - Fixed typos and made impovements pointed out by Boris Brezillon + + - Replaced kref with refcount_t as was suggested by Boris Brezillon + + - Corrected placement of got_sgt flag in the Lima driver, also renamed + flag to got_pages_sgt + + - Removed drm_gem_shmem_resv_assert_held() and made drm_gem_shmem_free() + to free pages without a new func that doesn't touch resv lock, as was + suggested by Boris Brezillon + + - Added pages_pin_count to drm_gem_shmem_print_info() + +v15:- Moved drm-shmem reference counters to use kref that allows to + optimize unlocked functions, like was suggested by Boris Brezillon. + + - Changed drm/gem/shmem function names to use _locked postfix and + dropped the _unlocked, making the naming scheme consistent across + DRM code, like was suggested by Boris Brezillon. + + - Added patch that fixes UAF in drm-shmem for drivers that import + dma-buf and then release buffer in the import error code path. + + - Added patch that makes drm-shmem use new flag for SGT's get_pages() + refcounting, preventing unbalanced refcounting when GEM is freed. + + - Fixed guest blob pinning in virtio-gpu driver that was missed + previously in the shrinker patch. + + - Moved VC4 and virtio-gpu drivers to use drm_gem_put() in + GEM-creation error code paths, which is now required by drm-shmem + and was missed in a previous patch versions. + + - Virtio-GPU now attaches shmem pages to host on first use and not + when BO is created. In older patch versions there was a potential + race condition in the BO creation code path where both + get_sgt()+object_attach() should've been made under same resv lock, + otherwise pages could be evicted before attachment is invoked. + + - Virtio-GPU and drm-shmem shrinker patches are split into smaller + ones. + +v14:- All the prerequisite reservation locking patches landed upstream, + previously were a part of this series in v13 and older. + + https://lore.kernel.org/dri-devel/20230529223935.2672495-1-dmitry.osipenko@collabora.com/ + + - Added patches to improve locked/unlocked function names, like was + suggested by Boris Brezillon for v13. + + - Made all exported drm-shmem symbols GPL, like was previously + discussed with Thomas Zimmermann on this series. + + - Improved virtio-gpu shrinker patch. Now it won't detach purged BO + when userspace closes GEM. Crosvm (and not qemu) checks res_id on + CMD_CTX_DETACH_RESOURCE and prints noisy error message if ID is + invalid, which wasn't noticed before. + +v13:- Updated virtio-gpu shrinker patch to use drm_gem_shmem_object_pin() + directly instead of drm_gem_pin() and dropped patch that exported + drm_gem_pin() functions, like was requested by Thomas Zimmermann in + v12. + +v12:- Fixed the "no previous prototype for function" warning reported by + kernel build bot for v11. + + - Fixed the missing reservation lock reported by Intel CI for VGEM + driver. Other drivers using drm-shmem were affected similarly to + VGEM. The problem was in the dma-buf attachment code path that led + to drm-shmem pinning function which assumed the held reservation lock + by drm_gem_pin(). In the past that code path was causing trouble for + i915 driver and we've changed the locking scheme for the attachment + code path in the dma-buf core to let exporters to handle the locking + themselves. After a closer investigation, I realized that my assumption + about testing of dma-buf export code path using Panfrost driver was + incorrect. Now I created additional local test to exrecise the Panfrost + export path. I also reproduced the issue reported by the Intel CI for + v10. It's all fixed now by making the drm_gem_shmem_pin() to take the + resv lock by itself. + + - Patches are based on top of drm-tip, CC'd intel-gfx CI for testing. + +v11:- Rebased on a recent linux-next. Added new patch as a result: + + drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() + + It's needed by the virtio-gpu driver to swap-in/unevict shmem + object, previously get_pages_sgt() didn't use locking. + + - Separated the "Add memory shrinker" patch into smaller parts to ease + the reviewing, as was requested by Thomas Zimmermann: + + drm/shmem-helper: Factor out pages alloc/release from + drm_gem_shmem_get/put_pages() + drm/shmem-helper: Add pages_pin_count field + drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin + drm/shmem-helper: Factor out unpinning part from drm_gem_shmem_purge() + + - Addessed the v10 review comments from Thomas Zimmermann: return errno + instead of bool, sort code alphabetically, rename function and etc + minor changes. + + - Added new patch to remove the "map->is_iomem" from drm-shmem, as + was suggested by Thomas Zimmermann. + + - Added acks and r-b's that were given to v10. + +v10:- Was partially applied to misc-fixes/next. + + https://lore.kernel.org/dri-devel/6c16f303-81df-7ebe-85e9-51bb40a8b301@collabora.com/T/ + +Boris Brezillon (1): + drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + +Dmitry Osipenko (29): + drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function + names + drm/gem: Add _locked postfix to functions that have unlocked + counterpart + drm/gem: Document locking rule of vmap and evict callbacks + drm/shmem-helper: Make all exported symbols GPL + drm/shmem-helper: Refactor locked/unlocked functions + drm/shmem-helper: Remove obsoleted is_iomem test + drm/shmem-helper: Add and use pages_pin_count + drm/shmem-helper: Use refcount_t for pages_use_count + drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() + drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin + drm/shmem-helper: Use refcount_t for vmap_use_count + drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition + drm/shmem-helper: Make drm_gem_shmem_get_pages() public + drm/shmem-helper: Add drm_gem_shmem_put_pages() + drm/shmem-helper: Avoid lockdep warning when pages are released + drm/lima: Explicitly get and put drm-shmem pages + drm/panfrost: Explicitly get and put drm-shmem pages + drm/virtio: Explicitly get and put drm-shmem pages + drm/v3d: Explicitly get and put drm-shmem pages + drm/shmem-helper: Change sgt allocation policy + drm/shmem-helper: Add common memory shrinker + drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() + drm/shmem-helper: Optimize unlocked get_pages_sgt() + drm/shmem-helper: Don't free refcounted GEM + drm/shmem-helper: Turn warnings about imported GEM into errors + drm/virtio: Pin display framebuffer BO + drm/virtio: Attach shmem BOs dynamically + drm/virtio: Support shmem shrinking + drm/panfrost: Switch to generic memory shrinker + + drivers/gpu/drm/drm_client.c | 6 +- + drivers/gpu/drm/drm_gem.c | 26 +- + drivers/gpu/drm/drm_gem_framebuffer_helper.c | 6 +- + drivers/gpu/drm/drm_gem_shmem_helper.c | 663 +++++++++++++++--- + drivers/gpu/drm/drm_internal.h | 4 +- + drivers/gpu/drm/drm_prime.c | 4 +- + drivers/gpu/drm/lima/lima_gem.c | 23 +- + drivers/gpu/drm/lima/lima_sched.c | 4 +- + drivers/gpu/drm/panfrost/Makefile | 1 - + drivers/gpu/drm/panfrost/panfrost_device.h | 4 - + drivers/gpu/drm/panfrost/panfrost_drv.c | 31 +- + drivers/gpu/drm/panfrost/panfrost_dump.c | 4 +- + drivers/gpu/drm/panfrost/panfrost_gem.c | 110 ++- + drivers/gpu/drm/panfrost/panfrost_gem.h | 9 - + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 127 ---- + drivers/gpu/drm/panfrost/panfrost_job.c | 18 +- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 39 +- + drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 6 +- + drivers/gpu/drm/v3d/v3d_bo.c | 11 +- + drivers/gpu/drm/virtio/virtgpu_drv.h | 22 +- + drivers/gpu/drm/virtio/virtgpu_gem.c | 85 +++ + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 57 +- + drivers/gpu/drm/virtio/virtgpu_kms.c | 8 + + drivers/gpu/drm/virtio/virtgpu_object.c | 143 +++- + drivers/gpu/drm/virtio/virtgpu_plane.c | 17 +- + drivers/gpu/drm/virtio/virtgpu_submit.c | 15 +- + drivers/gpu/drm/virtio/virtgpu_vq.c | 40 ++ + include/drm/drm_device.h | 10 +- + include/drm/drm_gem.h | 15 +- + include/drm/drm_gem_shmem_helper.h | 117 +++- + include/uapi/drm/virtgpu_drm.h | 14 + + 31 files changed, 1216 insertions(+), 423 deletions(-) + delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c + +-- +2.43.0 + + +^ permalink raw reply [flat|nested] 31+ messages in thread +* [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart Dmitry Osipenko + ` (28 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Make drm/gem API function names consistent by having locked function +use the _locked postfix in the name, while the unlocked variants don't +use the _unlocked postfix. Rename drm_gem_v/unmap() function names to +make them consistent with the rest of the API functions. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_client.c | 6 +++--- + drivers/gpu/drm/drm_gem.c | 20 ++++++++++---------- + drivers/gpu/drm/drm_gem_framebuffer_helper.c | 6 +++--- + drivers/gpu/drm/drm_internal.h | 4 ++-- + drivers/gpu/drm/drm_prime.c | 4 ++-- + drivers/gpu/drm/lima/lima_sched.c | 4 ++-- + drivers/gpu/drm/panfrost/panfrost_dump.c | 4 ++-- + drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 6 +++--- + include/drm/drm_gem.h | 4 ++-- + 9 files changed, 29 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c +index 9403b3f576f7..7ee9baf46eaa 100644 +--- a/drivers/gpu/drm/drm_client.c ++++ b/drivers/gpu/drm/drm_client.c +@@ -255,7 +255,7 @@ void drm_client_dev_restore(struct drm_device *dev) + static void drm_client_buffer_delete(struct drm_client_buffer *buffer) + { + if (buffer->gem) { +- drm_gem_vunmap_unlocked(buffer->gem, &buffer->map); ++ drm_gem_vunmap(buffer->gem, &buffer->map); + drm_gem_object_put(buffer->gem); + } + +@@ -339,7 +339,7 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer, + * fd_install step out of the driver backend hooks, to make that + * final step optional for internal users. + */ +- ret = drm_gem_vmap_unlocked(buffer->gem, map); ++ ret = drm_gem_vmap(buffer->gem, map); + if (ret) + return ret; + +@@ -361,7 +361,7 @@ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer) + { + struct iosys_map *map = &buffer->map; + +- drm_gem_vunmap_unlocked(buffer->gem, map); ++ drm_gem_vunmap(buffer->gem, map); + } + EXPORT_SYMBOL(drm_client_buffer_vunmap); + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 44a948b80ee1..95327b003692 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -1175,7 +1175,7 @@ void drm_gem_unpin(struct drm_gem_object *obj) + obj->funcs->unpin(obj); + } + +-int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) ++int drm_gem_vmap_locked(struct drm_gem_object *obj, struct iosys_map *map) + { + int ret; + +@@ -1192,9 +1192,9 @@ int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) + + return 0; + } +-EXPORT_SYMBOL(drm_gem_vmap); ++EXPORT_SYMBOL(drm_gem_vmap_locked); + +-void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) ++void drm_gem_vunmap_locked(struct drm_gem_object *obj, struct iosys_map *map) + { + dma_resv_assert_held(obj->resv); + +@@ -1207,27 +1207,27 @@ void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) + /* Always set the mapping to NULL. Callers may rely on this. */ + iosys_map_clear(map); + } +-EXPORT_SYMBOL(drm_gem_vunmap); ++EXPORT_SYMBOL(drm_gem_vunmap_locked); + +-int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map) ++int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) + { + int ret; + + dma_resv_lock(obj->resv, NULL); +- ret = drm_gem_vmap(obj, map); ++ ret = drm_gem_vmap_locked(obj, map); + dma_resv_unlock(obj->resv); + + return ret; + } +-EXPORT_SYMBOL(drm_gem_vmap_unlocked); ++EXPORT_SYMBOL(drm_gem_vmap); + +-void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map) ++void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) + { + dma_resv_lock(obj->resv, NULL); +- drm_gem_vunmap(obj, map); ++ drm_gem_vunmap_locked(obj, map); + dma_resv_unlock(obj->resv); + } +-EXPORT_SYMBOL(drm_gem_vunmap_unlocked); ++EXPORT_SYMBOL(drm_gem_vunmap); + + /** + * drm_gem_lock_reservations - Sets up the ww context and acquires +diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c +index 3bdb6ba37ff4..3808f47310bf 100644 +--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c ++++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c +@@ -362,7 +362,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, + ret = -EINVAL; + goto err_drm_gem_vunmap; + } +- ret = drm_gem_vmap_unlocked(obj, &map[i]); ++ ret = drm_gem_vmap(obj, &map[i]); + if (ret) + goto err_drm_gem_vunmap; + } +@@ -384,7 +384,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, + obj = drm_gem_fb_get_obj(fb, i); + if (!obj) + continue; +- drm_gem_vunmap_unlocked(obj, &map[i]); ++ drm_gem_vunmap(obj, &map[i]); + } + return ret; + } +@@ -411,7 +411,7 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map) + continue; + if (iosys_map_is_null(&map[i])) + continue; +- drm_gem_vunmap_unlocked(obj, &map[i]); ++ drm_gem_vunmap(obj, &map[i]); + } + } + EXPORT_SYMBOL(drm_gem_fb_vunmap); +diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h +index 8e4faf0a28e6..227f58e5b232 100644 +--- a/drivers/gpu/drm/drm_internal.h ++++ b/drivers/gpu/drm/drm_internal.h +@@ -172,8 +172,8 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, + + int drm_gem_pin(struct drm_gem_object *obj); + void drm_gem_unpin(struct drm_gem_object *obj); +-int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map); +-void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map); ++int drm_gem_vmap_locked(struct drm_gem_object *obj, struct iosys_map *map); ++void drm_gem_vunmap_locked(struct drm_gem_object *obj, struct iosys_map *map); + + /* drm_debugfs.c drm_debugfs_crc.c */ + #if defined(CONFIG_DEBUG_FS) +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 834a5e28abbe..4a5935a400ec 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -684,7 +684,7 @@ int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct iosys_map *map) + { + struct drm_gem_object *obj = dma_buf->priv; + +- return drm_gem_vmap(obj, map); ++ return drm_gem_vmap_locked(obj, map); + } + EXPORT_SYMBOL(drm_gem_dmabuf_vmap); + +@@ -700,7 +700,7 @@ void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map) + { + struct drm_gem_object *obj = dma_buf->priv; + +- drm_gem_vunmap(obj, map); ++ drm_gem_vunmap_locked(obj, map); + } + EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); + +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index c3bf8cda8498..3813f30480ba 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -371,7 +371,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) + } else { + buffer_chunk->size = lima_bo_size(bo); + +- ret = drm_gem_vmap_unlocked(&bo->base.base, &map); ++ ret = drm_gem_vmap(&bo->base.base, &map); + if (ret) { + kvfree(et); + goto out; +@@ -379,7 +379,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) + + memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size); + +- drm_gem_vunmap_unlocked(&bo->base.base, &map); ++ drm_gem_vunmap(&bo->base.base, &map); + } + + buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size; +diff --git a/drivers/gpu/drm/panfrost/panfrost_dump.c b/drivers/gpu/drm/panfrost/panfrost_dump.c +index 47751302f1bc..4042afe2fbf4 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_dump.c ++++ b/drivers/gpu/drm/panfrost/panfrost_dump.c +@@ -209,7 +209,7 @@ void panfrost_core_dump(struct panfrost_job *job) + goto dump_header; + } + +- ret = drm_gem_vmap_unlocked(&bo->base.base, &map); ++ ret = drm_gem_vmap(&bo->base.base, &map); + if (ret) { + dev_err(pfdev->dev, "Panfrost Dump: couldn't map Buffer Object\n"); + iter.hdr->bomap.valid = 0; +@@ -228,7 +228,7 @@ void panfrost_core_dump(struct panfrost_job *job) + vaddr = map.vaddr; + memcpy(iter.data, vaddr, bo->base.base.size); + +- drm_gem_vunmap_unlocked(&bo->base.base, &map); ++ drm_gem_vunmap(&bo->base.base, &map); + + iter.hdr->bomap.valid = 1; + +diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +index ba9b6e2b2636..52befead08c6 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c ++++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +@@ -106,7 +106,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, + goto err_close_bo; + } + +- ret = drm_gem_vmap_unlocked(&bo->base, &map); ++ ret = drm_gem_vmap(&bo->base, &map); + if (ret) + goto err_put_mapping; + perfcnt->buf = map.vaddr; +@@ -165,7 +165,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, + return 0; + + err_vunmap: +- drm_gem_vunmap_unlocked(&bo->base, &map); ++ drm_gem_vunmap(&bo->base, &map); + err_put_mapping: + panfrost_gem_mapping_put(perfcnt->mapping); + err_close_bo: +@@ -195,7 +195,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, + GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_OFF)); + + perfcnt->user = NULL; +- drm_gem_vunmap_unlocked(&perfcnt->mapping->obj->base.base, &map); ++ drm_gem_vunmap(&perfcnt->mapping->obj->base.base, &map); + perfcnt->buf = NULL; + panfrost_gem_close(&perfcnt->mapping->obj->base.base, file_priv); + panfrost_mmu_as_put(pfdev, perfcnt->mapping->mmu); +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index 369505447acd..decb19ffb2c8 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -527,8 +527,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj); + void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, + bool dirty, bool accessed); + +-int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map); +-void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map); ++int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map); ++void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map); + + int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles, + int count, struct drm_gem_object ***objs_out); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks Dmitry Osipenko + ` (27 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add _locked postfix to drm_gem functions that have unlocked counterpart +functions to make GEM functions naming more consistent and intuitive in +regards to the locking requirements. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem.c | 6 +++--- + include/drm/drm_gem.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 95327b003692..4523cd40fb2f 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -1490,10 +1490,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru, + EXPORT_SYMBOL(drm_gem_lru_scan); + + /** +- * drm_gem_evict - helper to evict backing pages for a GEM object ++ * drm_gem_evict_locked - helper to evict backing pages for a GEM object + * @obj: obj in question + */ +-int drm_gem_evict(struct drm_gem_object *obj) ++int drm_gem_evict_locked(struct drm_gem_object *obj) + { + dma_resv_assert_held(obj->resv); + +@@ -1505,4 +1505,4 @@ int drm_gem_evict(struct drm_gem_object *obj) + + return 0; + } +-EXPORT_SYMBOL(drm_gem_evict); ++EXPORT_SYMBOL(drm_gem_evict_locked); +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index decb19ffb2c8..f835fdee6a5e 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -551,7 +551,7 @@ unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, + unsigned long *remaining, + bool (*shrink)(struct drm_gem_object *obj)); + +-int drm_gem_evict(struct drm_gem_object *obj); ++int drm_gem_evict_locked(struct drm_gem_object *obj); + + #ifdef CONFIG_LOCKDEP + /** +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL Dmitry Osipenko + ` (26 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +The vmap/vunmap/evict GEM callbacks are always invoked with a held GEM's +reservation lock. Document this locking rule for clarity. + +Signed-off-by: Dmitry Osipenko +--- + include/drm/drm_gem.h | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index f835fdee6a5e..021f64371056 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -156,7 +156,8 @@ struct drm_gem_object_funcs { + * @vmap: + * + * Returns a virtual address for the buffer. Used by the +- * drm_gem_dmabuf_vmap() helper. ++ * drm_gem_dmabuf_vmap() helper. Called with a held GEM reservation ++ * lock. + * + * This callback is optional. + */ +@@ -166,7 +167,8 @@ struct drm_gem_object_funcs { + * @vunmap: + * + * Releases the address previously returned by @vmap. Used by the +- * drm_gem_dmabuf_vunmap() helper. ++ * drm_gem_dmabuf_vunmap() helper. Called with a held GEM reservation ++ * lock. + * + * This callback is optional. + */ +@@ -189,7 +191,8 @@ struct drm_gem_object_funcs { + * @evict: + * + * Evicts gem object out from memory. Used by the drm_gem_object_evict() +- * helper. Returns 0 on success, -errno otherwise. ++ * helper. Returns 0 on success, -errno otherwise. Called with a held ++ * GEM reservation lock. + * + * This callback is optional. + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (2 preceding siblings ...) + 2024-01-05 18:45 ` [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:45 ` [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions Dmitry Osipenko + ` (25 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Make all drm-shmem exported symbols GPL to make them consistent with +the rest of drm-shmem symbols. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index e435f986cd13..0d61f2b3e213 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -226,7 +226,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) + shmem->pages_mark_accessed_on_put); + shmem->pages = NULL; + } +-EXPORT_SYMBOL(drm_gem_shmem_put_pages); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); + + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { +@@ -271,7 +271,7 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) + + return ret; + } +-EXPORT_SYMBOL(drm_gem_shmem_pin); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_pin); + + /** + * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object +@@ -290,7 +290,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + drm_gem_shmem_unpin_locked(shmem); + dma_resv_unlock(shmem->base.resv); + } +-EXPORT_SYMBOL(drm_gem_shmem_unpin); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); + + /* + * drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object +@@ -360,7 +360,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + + return ret; + } +-EXPORT_SYMBOL(drm_gem_shmem_vmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap); + + /* + * drm_gem_shmem_vunmap - Unmap a virtual mapping for a shmem GEM object +@@ -396,7 +396,7 @@ void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, + + shmem->vaddr = NULL; + } +-EXPORT_SYMBOL(drm_gem_shmem_vunmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap); + + static int + drm_gem_shmem_create_with_handle(struct drm_file *file_priv, +@@ -435,7 +435,7 @@ int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) + + return (madv >= 0); + } +-EXPORT_SYMBOL(drm_gem_shmem_madvise); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise); + + void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + { +@@ -467,7 +467,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + + invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); + } +-EXPORT_SYMBOL(drm_gem_shmem_purge); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_purge); + + /** + * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object +@@ -642,7 +642,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); + } +-EXPORT_SYMBOL(drm_gem_shmem_print_info); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); + + /** + * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (3 preceding siblings ...) + 2024-01-05 18:45 ` [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL Dmitry Osipenko +@ 2024-01-05 18:45 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test Dmitry Osipenko + ` (24 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:45 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add locked and remove unlocked postfixes from drm-shmem function names, +making names consistent with the drm/gem core code. + +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 60 +++++++++---------- + drivers/gpu/drm/lima/lima_gem.c | 6 +- + drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- + drivers/gpu/drm/panfrost/panfrost_gem.c | 2 +- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- + include/drm/drm_gem_shmem_helper.h | 28 ++++----- + 7 files changed, 51 insertions(+), 51 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 0d61f2b3e213..043e8e3b129c 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -153,7 +153,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + kfree(shmem->sgt); + } + if (shmem->pages) +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + + drm_WARN_ON(obj->dev, shmem->pages_use_count); + +@@ -165,7 +165,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_free); + +-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) ++static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + struct page **pages; +@@ -199,12 +199,12 @@ static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + } + + /* +- * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a shmem GEM object ++ * drm_gem_shmem_put_pages_locked - Decrease use count on the backing pages for a shmem GEM object + * @shmem: shmem GEM object + * + * This function decreases the use count and puts the backing pages when use drops to zero. + */ +-void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) ++void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + +@@ -226,7 +226,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) + shmem->pages_mark_accessed_on_put); + shmem->pages = NULL; + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { +@@ -234,7 +234,7 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + + return ret; + } +@@ -243,7 +243,7 @@ static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) + { + dma_resv_assert_held(shmem->base.resv); + +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + } + + /** +@@ -293,7 +293,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); + + /* +- * drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object ++ * drm_gem_shmem_vmap_locked - Create a virtual mapping for a shmem GEM object + * @shmem: shmem GEM object + * @map: Returns the kernel virtual address of the SHMEM GEM object's backing + * store. +@@ -302,13 +302,13 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); + * exists for the buffer backing the shmem GEM object. It hides the differences + * between dma-buf imported and natively allocated objects. + * +- * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap(). ++ * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap_locked(). + * + * Returns: + * 0 on success or a negative error code on failure. + */ +-int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map) ++int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map) + { + struct drm_gem_object *obj = &shmem->base; + int ret = 0; +@@ -331,7 +331,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + return 0; + } + +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + if (ret) + goto err_zero_use; + +@@ -354,28 +354,28 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + + err_put_pages: + if (!obj->import_attach) +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + err_zero_use: + shmem->vmap_use_count = 0; + + return ret; + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap_locked); + + /* +- * drm_gem_shmem_vunmap - Unmap a virtual mapping for a shmem GEM object ++ * drm_gem_shmem_vunmap_locked - Unmap a virtual mapping for a shmem GEM object + * @shmem: shmem GEM object + * @map: Kernel virtual address where the SHMEM GEM object was mapped + * + * This function cleans up a kernel virtual address mapping acquired by +- * drm_gem_shmem_vmap(). The mapping is only removed when the use count drops to +- * zero. ++ * drm_gem_shmem_vmap_locked(). The mapping is only removed when the use count ++ * drops to zero. + * + * This function hides the differences between dma-buf imported and natively + * allocated objects. + */ +-void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map) ++void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map) + { + struct drm_gem_object *obj = &shmem->base; + +@@ -391,12 +391,12 @@ void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, + return; + + vunmap(shmem->vaddr); +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + } + + shmem->vaddr = NULL; + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap_locked); + + static int + drm_gem_shmem_create_with_handle(struct drm_file *file_priv, +@@ -424,7 +424,7 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv, + /* Update madvise status, returns true if not purged, else + * false or -errno. + */ +-int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) ++int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv) + { + dma_resv_assert_held(shmem->base.resv); + +@@ -435,9 +435,9 @@ int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) + + return (madv >= 0); + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked); + +-void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) ++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + struct drm_device *dev = obj->dev; +@@ -451,7 +451,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + kfree(shmem->sgt); + shmem->sgt = NULL; + +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + + shmem->madv = -1; + +@@ -467,7 +467,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) + + invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); + } +-EXPORT_SYMBOL_GPL(drm_gem_shmem_purge); ++EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked); + + /** + * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object +@@ -564,7 +564,7 @@ static void drm_gem_shmem_vm_close(struct vm_area_struct *vma) + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + + dma_resv_lock(shmem->base.resv, NULL); +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + dma_resv_unlock(shmem->base.resv); + + drm_gem_vm_close(vma); +@@ -611,7 +611,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct + } + + dma_resv_lock(shmem->base.resv, NULL); +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + dma_resv_unlock(shmem->base.resv); + + if (ret) +@@ -679,7 +679,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + + drm_WARN_ON(obj->dev, obj->import_attach); + +- ret = drm_gem_shmem_get_pages(shmem); ++ ret = drm_gem_shmem_get_pages_locked(shmem); + if (ret) + return ERR_PTR(ret); + +@@ -701,7 +701,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + sg_free_table(sgt); + kfree(sgt); + err_put_pages: +- drm_gem_shmem_put_pages(shmem); ++ drm_gem_shmem_put_pages_locked(shmem); + return ERR_PTR(ret); + } + +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index 4f9736e5f929..433bda72e59b 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -180,7 +180,7 @@ static int lima_gem_pin(struct drm_gem_object *obj) + if (bo->heap_size) + return -EINVAL; + +- return drm_gem_shmem_pin(&bo->base); ++ return drm_gem_shmem_object_pin(obj); + } + + static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) +@@ -190,7 +190,7 @@ static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) + if (bo->heap_size) + return -EINVAL; + +- return drm_gem_shmem_vmap(&bo->base, map); ++ return drm_gem_shmem_object_vmap(obj, map); + } + + static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +@@ -200,7 +200,7 @@ static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) + if (bo->heap_size) + return -EINVAL; + +- return drm_gem_shmem_mmap(&bo->base, vma); ++ return drm_gem_shmem_object_mmap(obj, vma); + } + + static const struct drm_gem_object_funcs lima_gem_funcs = { +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index a926d71e8131..a15d62f19afb 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -438,7 +438,7 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + } + } + +- args->retained = drm_gem_shmem_madvise(&bo->base, args->madv); ++ args->retained = drm_gem_shmem_madvise_locked(&bo->base, args->madv); + + if (args->retained) { + if (args->madv == PANFROST_MADV_DONTNEED) +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index d47b40b82b0b..f268bd5c2884 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -192,7 +192,7 @@ static int panfrost_gem_pin(struct drm_gem_object *obj) + if (bo->is_heap) + return -EINVAL; + +- return drm_gem_shmem_pin(&bo->base); ++ return drm_gem_shmem_object_pin(obj); + } + + static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object *obj) +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +index 3d9f51bd48b6..02b60ea1433a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +@@ -51,7 +51,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) + goto unlock_mappings; + + panfrost_gem_teardown_mappings_locked(bo); +- drm_gem_shmem_purge(&bo->base); ++ drm_gem_shmem_purge_locked(&bo->base); + ret = true; + + dma_resv_unlock(shmem->base.resv); +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index f38385fe76bb..1ab081bd81a8 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -538,7 +538,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + err_map: + sg_free_table(sgt); + err_pages: +- drm_gem_shmem_put_pages(&bo->base); ++ drm_gem_shmem_put_pages_locked(&bo->base); + err_unlock: + dma_resv_unlock(obj->resv); + err_bo: +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index bf0c31aa8fbe..9e83212becbb 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -99,16 +99,16 @@ struct drm_gem_shmem_object { + struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size); + void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); + +-void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); ++void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); + int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem); +-int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map); +-void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, +- struct iosys_map *map); ++int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map); ++void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, ++ struct iosys_map *map); + int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma); + +-int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv); ++int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv); + + static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) + { +@@ -117,7 +117,7 @@ static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem + !shmem->base.dma_buf && !shmem->base.import_attach; + } + +-void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem); ++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem); + + struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem); + struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem); +@@ -208,12 +208,12 @@ static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_ + } + + /* +- * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap() ++ * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap_locked() + * @obj: GEM object + * @map: Returns the kernel virtual address of the SHMEM GEM object's backing store. + * +- * This function wraps drm_gem_shmem_vmap(). Drivers that employ the shmem helpers should +- * use it as their &drm_gem_object_funcs.vmap handler. ++ * This function wraps drm_gem_shmem_vmap_locked(). Drivers that employ the shmem ++ * helpers should use it as their &drm_gem_object_funcs.vmap handler. + * + * Returns: + * 0 on success or a negative error code on failure. +@@ -223,7 +223,7 @@ static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, + { + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + +- return drm_gem_shmem_vmap(shmem, map); ++ return drm_gem_shmem_vmap_locked(shmem, map); + } + + /* +@@ -231,15 +231,15 @@ static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, + * @obj: GEM object + * @map: Kernel virtual address where the SHMEM GEM object was mapped + * +- * This function wraps drm_gem_shmem_vunmap(). Drivers that employ the shmem helpers should +- * use it as their &drm_gem_object_funcs.vunmap handler. ++ * This function wraps drm_gem_shmem_vunmap_locked(). Drivers that employ the shmem ++ * helpers should use it as their &drm_gem_object_funcs.vunmap handler. + */ + static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, + struct iosys_map *map) + { + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + +- drm_gem_shmem_vunmap(shmem, map); ++ drm_gem_shmem_vunmap_locked(shmem, map); + } + + /** +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (4 preceding siblings ...) + 2024-01-05 18:45 ` [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count Dmitry Osipenko + ` (23 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Everything that uses the mapped buffer should be agnostic to is_iomem. +The only reason for the is_iomem test is that we're setting shmem->vaddr +to the returned map->vaddr. Now that the shmem->vaddr code is gone, remove +the obsoleted is_iomem test to clean up the code. + +Acked-by: Maxime Ripard +Suggested-by: Thomas Zimmermann +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 043e8e3b129c..1f0a66386415 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -315,12 +315,6 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + + if (obj->import_attach) { + ret = dma_buf_vmap(obj->import_attach->dmabuf, map); +- if (!ret) { +- if (drm_WARN_ON(obj->dev, map->is_iomem)) { +- dma_buf_vunmap(obj->import_attach->dmabuf, map); +- return -EIO; +- } +- } + } else { + pgprot_t prot = PAGE_KERNEL; + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (5 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count Dmitry Osipenko + ` (22 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add separate pages_pin_count for tracking of whether drm-shmem pages are +moveable or not. With the addition of memory shrinker support to drm-shmem, +the pages_use_count will no longer determine whether pages are hard-pinned +in memory, but whether pages exist and are soft-pinned (and could be swapped +out). The pages_pin_count > 1 will hard-pin pages in memory. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 25 +++++++++++++++++-------- + include/drm/drm_gem_shmem_helper.h | 11 +++++++++++ + 2 files changed, 28 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 1f0a66386415..55b9dd3d4b18 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -156,6 +156,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + drm_gem_shmem_put_pages_locked(shmem); + + drm_WARN_ON(obj->dev, shmem->pages_use_count); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); + + dma_resv_unlock(shmem->base.resv); + } +@@ -234,18 +235,16 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + ++ if (refcount_inc_not_zero(&shmem->pages_pin_count)) ++ return 0; ++ + ret = drm_gem_shmem_get_pages_locked(shmem); ++ if (!ret) ++ refcount_set(&shmem->pages_pin_count, 1); + + return ret; + } + +-static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) +-{ +- dma_resv_assert_held(shmem->base.resv); +- +- drm_gem_shmem_put_pages_locked(shmem); +-} +- + /** + * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object + * @shmem: shmem GEM object +@@ -263,6 +262,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) + + drm_WARN_ON(obj->dev, obj->import_attach); + ++ if (refcount_inc_not_zero(&shmem->pages_pin_count)) ++ return 0; ++ + ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); + if (ret) + return ret; +@@ -286,8 +288,14 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + + drm_WARN_ON(obj->dev, obj->import_attach); + ++ if (refcount_dec_not_one(&shmem->pages_pin_count)) ++ return; ++ + dma_resv_lock(shmem->base.resv, NULL); +- drm_gem_shmem_unpin_locked(shmem); ++ ++ if (refcount_dec_and_test(&shmem->pages_pin_count)) ++ drm_gem_shmem_put_pages_locked(shmem); ++ + dma_resv_unlock(shmem->base.resv); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); +@@ -632,6 +640,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + if (shmem->base.import_attach) + return; + ++ drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); + drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count); + drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 9e83212becbb..c708a9f45cbd 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -39,6 +39,17 @@ struct drm_gem_shmem_object { + */ + unsigned int pages_use_count; + ++ /** ++ * @pages_pin_count: ++ * ++ * Reference count on the pinned pages table. ++ * ++ * Pages are hard-pinned and reside in memory if count ++ * greater than zero. Otherwise, when count is zero, the pages are ++ * allowed to be evicted and purged by memory shrinker. ++ */ ++ refcount_t pages_pin_count; ++ + /** + * @madv: State for madvise + * +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (6 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() Dmitry Osipenko + ` (21 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Use atomic refcount_t helper for pages_use_count to optimize pin/unpin +functions by skipping reservation locking while GEM's pin refcount > 1. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 33 +++++++++++-------------- + drivers/gpu/drm/lima/lima_gem.c | 2 +- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- + include/drm/drm_gem_shmem_helper.h | 2 +- + 4 files changed, 18 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 55b9dd3d4b18..cacf0f8c42e2 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -155,7 +155,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + if (shmem->pages) + drm_gem_shmem_put_pages_locked(shmem); + +- drm_WARN_ON(obj->dev, shmem->pages_use_count); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); + + dma_resv_unlock(shmem->base.resv); +@@ -173,14 +173,13 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + +- if (shmem->pages_use_count++ > 0) ++ if (refcount_inc_not_zero(&shmem->pages_use_count)) + return 0; + + pages = drm_gem_get_pages(obj); + if (IS_ERR(pages)) { + drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n", + PTR_ERR(pages)); +- shmem->pages_use_count = 0; + return PTR_ERR(pages); + } + +@@ -196,6 +195,8 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + + shmem->pages = pages; + ++ refcount_set(&shmem->pages_use_count, 1); ++ + return 0; + } + +@@ -211,21 +212,17 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + + dma_resv_assert_held(shmem->base.resv); + +- if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count)) +- return; +- +- if (--shmem->pages_use_count > 0) +- return; +- ++ if (refcount_dec_and_test(&shmem->pages_use_count)) { + #ifdef CONFIG_X86 +- if (shmem->map_wc) +- set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); ++ if (shmem->map_wc) ++ set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); + #endif + +- drm_gem_put_pages(obj, shmem->pages, +- shmem->pages_mark_dirty_on_put, +- shmem->pages_mark_accessed_on_put); +- shmem->pages = NULL; ++ drm_gem_put_pages(obj, shmem->pages, ++ shmem->pages_mark_dirty_on_put, ++ shmem->pages_mark_accessed_on_put); ++ shmem->pages = NULL; ++ } + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +@@ -552,8 +549,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) + * mmap'd, vm_open() just grabs an additional reference for the new + * mm the vma is getting copied into (ie. on fork()). + */ +- if (!drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count)) +- shmem->pages_use_count++; ++ drm_WARN_ON_ONCE(obj->dev, ++ !refcount_inc_not_zero(&shmem->pages_use_count)); + + dma_resv_unlock(shmem->base.resv); + +@@ -641,7 +638,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + return; + + drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); +- drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count); ++ drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); + drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); + } +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index 433bda72e59b..2a97aa85416b 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -47,7 +47,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) + } + + bo->base.pages = pages; +- bo->base.pages_use_count = 1; ++ refcount_set(&bo->base.pages_use_count, 1); + + mapping_set_unevictable(mapping); + } +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 1ab081bd81a8..bd5a0073009d 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -489,7 +489,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + goto err_unlock; + } + bo->base.pages = pages; +- bo->base.pages_use_count = 1; ++ refcount_set(&bo->base.pages_use_count, 1); + } else { + pages = bo->base.pages; + if (pages[page_offset]) { +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index c708a9f45cbd..2c5dc62df20c 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -37,7 +37,7 @@ struct drm_gem_shmem_object { + * Reference count on the pages table. + * The pages are put when the count reaches zero. + */ +- unsigned int pages_use_count; ++ refcount_t pages_use_count; + + /** + * @pages_pin_count: +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (7 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin Dmitry Osipenko + ` (20 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Add lockless drm_gem_shmem_get_pages() helper that skips taking reservation +lock if pages_use_count is non-zero, leveraging from atomicity of the +refcount_t. Make drm_gem_shmem_mmap() to utilize the new helper. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index cacf0f8c42e2..1c032513abf1 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -226,6 +226,20 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + ++static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) ++{ ++ int ret; ++ ++ if (refcount_inc_not_zero(&shmem->pages_use_count)) ++ return 0; ++ ++ dma_resv_lock(shmem->base.resv, NULL); ++ ret = drm_gem_shmem_get_pages_locked(shmem); ++ dma_resv_unlock(shmem->base.resv); ++ ++ return ret; ++} ++ + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { + int ret; +@@ -609,10 +623,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct + return ret; + } + +- dma_resv_lock(shmem->base.resv, NULL); +- ret = drm_gem_shmem_get_pages_locked(shmem); +- dma_resv_unlock(shmem->base.resv); +- ++ ret = drm_gem_shmem_get_pages(shmem); + if (ret) + return ret; + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (8 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count Dmitry Osipenko + ` (19 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +The vmapped pages shall be pinned in memory and previously get/put_pages() +were implicitly hard-pinning/unpinning the pages. This will no longer be +the case with addition of memory shrinker because pages_use_count > 0 won't +determine anymore whether pages are hard-pinned (they will be soft-pinned), +while the new pages_pin_count will do the hard-pinning. Switch the +vmap/vunmap() to use pin/unpin() functions in a preparation of addition +of the memory shrinker support to drm-shmem. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 19 ++++++++++++------- + include/drm/drm_gem_shmem_helper.h | 2 +- + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 1c032513abf1..9c89183f81b7 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -256,6 +256,14 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + return ret; + } + ++static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) ++{ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (refcount_dec_and_test(&shmem->pages_pin_count)) ++ drm_gem_shmem_put_pages_locked(shmem); ++} ++ + /** + * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object + * @shmem: shmem GEM object +@@ -303,10 +311,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) + return; + + dma_resv_lock(shmem->base.resv, NULL); +- +- if (refcount_dec_and_test(&shmem->pages_pin_count)) +- drm_gem_shmem_put_pages_locked(shmem); +- ++ drm_gem_shmem_unpin_locked(shmem); + dma_resv_unlock(shmem->base.resv); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); +@@ -344,7 +349,7 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + return 0; + } + +- ret = drm_gem_shmem_get_pages_locked(shmem); ++ ret = drm_gem_shmem_pin_locked(shmem); + if (ret) + goto err_zero_use; + +@@ -367,7 +372,7 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + + err_put_pages: + if (!obj->import_attach) +- drm_gem_shmem_put_pages_locked(shmem); ++ drm_gem_shmem_unpin_locked(shmem); + err_zero_use: + shmem->vmap_use_count = 0; + +@@ -404,7 +409,7 @@ void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, + return; + + vunmap(shmem->vaddr); +- drm_gem_shmem_put_pages_locked(shmem); ++ drm_gem_shmem_unpin_locked(shmem); + } + + shmem->vaddr = NULL; +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 2c5dc62df20c..80623b897803 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -124,7 +124,7 @@ int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv); + static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) + { + return (shmem->madv > 0) && +- !shmem->vmap_use_count && shmem->sgt && ++ !refcount_read(&shmem->pages_pin_count) && shmem->sgt && + !shmem->base.dma_buf && !shmem->base.import_attach; + } + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (9 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition Dmitry Osipenko + ` (18 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Use refcount_t helper for vmap_use_count to make refcounting consistent +with pages_use_count and pages_pin_count that use refcount_t. This also +makes vmapping to benefit from the refcount_t's overflow checks. + +Acked-by: Maxime Ripard +Reviewed-by: Boris Brezillon +Suggested-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 28 +++++++++++--------------- + include/drm/drm_gem_shmem_helper.h | 2 +- + 2 files changed, 13 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 9c89183f81b7..3403700780c3 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -144,7 +144,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + } else { + dma_resv_lock(shmem->base.resv, NULL); + +- drm_WARN_ON(obj->dev, shmem->vmap_use_count); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); + + if (shmem->sgt) { + dma_unmap_sgtable(obj->dev->dev, shmem->sgt, +@@ -344,23 +344,25 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + + dma_resv_assert_held(shmem->base.resv); + +- if (shmem->vmap_use_count++ > 0) { ++ if (refcount_inc_not_zero(&shmem->vmap_use_count)) { + iosys_map_set_vaddr(map, shmem->vaddr); + return 0; + } + + ret = drm_gem_shmem_pin_locked(shmem); + if (ret) +- goto err_zero_use; ++ return ret; + + if (shmem->map_wc) + prot = pgprot_writecombine(prot); + shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, + VM_MAP, prot); +- if (!shmem->vaddr) ++ if (!shmem->vaddr) { + ret = -ENOMEM; +- else ++ } else { + iosys_map_set_vaddr(map, shmem->vaddr); ++ refcount_set(&shmem->vmap_use_count, 1); ++ } + } + + if (ret) { +@@ -373,8 +375,6 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + err_put_pages: + if (!obj->import_attach) + drm_gem_shmem_unpin_locked(shmem); +-err_zero_use: +- shmem->vmap_use_count = 0; + + return ret; + } +@@ -402,14 +402,10 @@ void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, + } else { + dma_resv_assert_held(shmem->base.resv); + +- if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count)) +- return; +- +- if (--shmem->vmap_use_count > 0) +- return; +- +- vunmap(shmem->vaddr); +- drm_gem_shmem_unpin_locked(shmem); ++ if (refcount_dec_and_test(&shmem->vmap_use_count)) { ++ vunmap(shmem->vaddr); ++ drm_gem_shmem_unpin_locked(shmem); ++ } + } + + shmem->vaddr = NULL; +@@ -655,7 +651,7 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + + drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); + drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); +- drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); ++ drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count)); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 80623b897803..18020f653d7e 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -82,7 +82,7 @@ struct drm_gem_shmem_object { + * Reference count on the virtual address. + * The address are un-mapped when the count reaches zero. + */ +- unsigned int vmap_use_count; ++ refcount_t vmap_use_count; + + /** + * @pages_mark_dirty_on_put: +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (10 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public Dmitry Osipenko + ` (17 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Prepare drm_gem_shmem_free() to addition of memory shrinker support +to drm-shmem by adding and using variant of put_pages() that doesn't +touch reservation lock. Reservation shouldn't be touched because lockdep +will trigger a bogus warning about locking contention with fs_reclaim +code paths that can't happen during the time when GEM is freed and +lockdep doesn't know about that. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 40 ++++++++++++++------------ + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 3403700780c3..799a3c5015ad 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -128,6 +128,22 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_create); + ++static void ++drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ ++#ifdef CONFIG_X86 ++ if (shmem->map_wc) ++ set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); ++#endif ++ ++ drm_gem_put_pages(obj, shmem->pages, ++ shmem->pages_mark_dirty_on_put, ++ shmem->pages_mark_accessed_on_put); ++ shmem->pages = NULL; ++} ++ + /** + * drm_gem_shmem_free - Free resources associated with a shmem GEM object + * @shmem: shmem GEM object to free +@@ -142,8 +158,6 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + if (obj->import_attach) { + drm_prime_gem_destroy(obj, shmem->sgt); + } else { +- dma_resv_lock(shmem->base.resv, NULL); +- + drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); + + if (shmem->sgt) { +@@ -152,13 +166,12 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + sg_free_table(shmem->sgt); + kfree(shmem->sgt); + } +- if (shmem->pages) +- drm_gem_shmem_put_pages_locked(shmem); ++ if (shmem->pages && ++ refcount_dec_and_test(&shmem->pages_use_count)) ++ drm_gem_shmem_free_pages(shmem); + + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); +- +- dma_resv_unlock(shmem->base.resv); + } + + drm_gem_object_release(obj); +@@ -208,21 +221,10 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + */ + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + { +- struct drm_gem_object *obj = &shmem->base; +- + dma_resv_assert_held(shmem->base.resv); + +- if (refcount_dec_and_test(&shmem->pages_use_count)) { +-#ifdef CONFIG_X86 +- if (shmem->map_wc) +- set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); +-#endif +- +- drm_gem_put_pages(obj, shmem->pages, +- shmem->pages_mark_dirty_on_put, +- shmem->pages_mark_accessed_on_put); +- shmem->pages = NULL; +- } ++ if (refcount_dec_and_test(&shmem->pages_use_count)) ++ drm_gem_shmem_free_pages(shmem); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (11 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() Dmitry Osipenko + ` (16 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +We're going to move away from having implicit get_pages() done by +get_pages_sgt() to simplify refcnt handling. Drivers will manage +get/put_pages() by themselves. Expose the drm_gem_shmem_get_pages() +in a public drm-shmem API. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 10 +++++++++- + include/drm/drm_gem_shmem_helper.h | 1 + + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 799a3c5015ad..dc416a4bce1b 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -228,7 +228,14 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) ++/* ++ * drm_gem_shmem_get_pages - Increase use count on the backing pages for a shmem GEM object ++ * @shmem: shmem GEM object ++ * ++ * This function Increases the use count and allocates the backing pages if ++ * use-count equals to zero. ++ */ ++int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + { + int ret; + +@@ -241,6 +248,7 @@ static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + + return ret; + } ++EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages); + + static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + { +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 18020f653d7e..6dedc0739fbc 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -110,6 +110,7 @@ struct drm_gem_shmem_object { + struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size); + void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); + ++int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); + int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (12 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released Dmitry Osipenko + ` (15 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +We're going to move away from having implicit get_pages() done by +get_pages_sgt() to ease simplify refcnt handling. Drivers will manage +get/put_pages() by themselves. Add drm_gem_shmem_put_pages(). + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 20 ++++++++++++++++++++ + include/drm/drm_gem_shmem_helper.h | 1 + + 2 files changed, 21 insertions(+) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index dc416a4bce1b..f5ed64f78648 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -218,6 +218,7 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + * @shmem: shmem GEM object + * + * This function decreases the use count and puts the backing pages when use drops to zero. ++ * Caller must hold GEM's reservation lock. + */ + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + { +@@ -228,6 +229,25 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + ++/* ++ * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a shmem GEM object ++ * @shmem: shmem GEM object ++ * ++ * This function decreases the use count and puts the backing pages when use drops to zero. ++ * It's unlocked version of drm_gem_shmem_put_pages_locked(), caller must not hold ++ * GEM's reservation lock. ++ */ ++void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) ++{ ++ if (refcount_dec_not_one(&shmem->pages_use_count)) ++ return; ++ ++ dma_resv_lock(shmem->base.resv, NULL); ++ drm_gem_shmem_put_pages_locked(shmem); ++ dma_resv_unlock(shmem->base.resv); ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); ++ + /* + * drm_gem_shmem_get_pages - Increase use count on the backing pages for a shmem GEM object + * @shmem: shmem GEM object +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 6dedc0739fbc..525480488451 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -111,6 +111,7 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t + void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); + + int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem); ++void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); + int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (13 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages Dmitry Osipenko + ` (14 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +All drivers will be moved to get/put pages explicitly and then the last +put_pages() will be invoked during gem_free() time by some drivers. +We can't touch reservation lock when GEM is freed because that will cause +a spurious warning from lockdep when shrinker support will be added. +Lockdep doesn't know that fs_reclaim isn't functioning for a freed object, +and thus, can't deadlock. Release pages directly without taking reservation +lock if GEM is freed and its refcount is zero. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index f5ed64f78648..c7357110ca76 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -242,6 +242,22 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem) + if (refcount_dec_not_one(&shmem->pages_use_count)) + return; + ++ /* ++ * Destroying the object is a special case because acquiring ++ * the obj lock can cause a locking order inversion between ++ * reservation_ww_class_mutex and fs_reclaim. ++ * ++ * This deadlock is not actually possible, because no one should ++ * be already holding the lock when GEM is released. Unfortunately ++ * lockdep is not aware of this detail. So when the refcount drops ++ * to zero, we pretend it is already locked. ++ */ ++ if (!kref_read(&shmem->base.refcount)) { ++ if (refcount_dec_and_test(&shmem->pages_use_count)) ++ drm_gem_shmem_free_pages(shmem); ++ return; ++ } ++ + dma_resv_lock(shmem->base.resv, NULL); + drm_gem_shmem_put_pages_locked(shmem); + dma_resv_unlock(shmem->base.resv); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (14 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Dmitry Osipenko + ` (13 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +To simplify the drm-shmem refcnt handling, we're moving away from +the implicit get_pages() that is used by get_pages_sgt(). From now on +drivers will have to pin pages while they use sgt. Lima driver doesn't +have shrinker, hence pages are pinned and sgt is valid as long as pages' +use-count > 0. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/lima/lima_gem.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c +index 2a97aa85416b..9c3e34a7fbed 100644 +--- a/drivers/gpu/drm/lima/lima_gem.c ++++ b/drivers/gpu/drm/lima/lima_gem.c +@@ -115,6 +115,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + return PTR_ERR(shmem); + + obj = &shmem->base; ++ bo = to_lima_bo(obj); + + /* Mali Utgard GPU can only support 32bit address space */ + mask = mapping_gfp_mask(obj->filp->f_mapping); +@@ -123,13 +124,17 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + mapping_set_gfp_mask(obj->filp->f_mapping, mask); + + if (is_heap) { +- bo = to_lima_bo(obj); + err = lima_heap_alloc(bo, NULL); + if (err) + goto out; + } else { +- struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem); ++ struct sg_table *sgt; + ++ err = drm_gem_shmem_get_pages(shmem); ++ if (err) ++ goto out; ++ ++ sgt = drm_gem_shmem_get_pages_sgt(shmem); + if (IS_ERR(sgt)) { + err = PTR_ERR(sgt); + goto out; +@@ -139,6 +144,9 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, + err = drm_gem_handle_create(file, obj, handle); + + out: ++ if (err && refcount_read(&bo->base.pages_use_count)) ++ drm_gem_shmem_put_pages(shmem); ++ + /* drop reference from allocate - handle holds it now */ + drm_gem_object_put(obj); + +@@ -152,6 +160,9 @@ static void lima_gem_free_object(struct drm_gem_object *obj) + if (!list_empty(&bo->va)) + dev_err(obj->dev->dev, "lima gem free bo still has va\n"); + ++ if (refcount_read(&bo->base.pages_use_count)) ++ drm_gem_shmem_put_pages(&bo->base); ++ + drm_gem_shmem_free(&bo->base); + } + +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (15 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages Dmitry Osipenko + ` (12 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +From: Boris Brezillon + +If some the pages or sgt allocation failed, we shouldn't release the +pages ref we got earlier, otherwise we will end up with unbalanced +get/put_pages() calls. We should instead leave everything in place +and let the BO release function deal with extra cleanup when the object +is destroyed, or let the fault handler try again next time it's called. + +Fixes: 187d2929206e ("drm/panfrost: Add support for GPU heap allocations") +Cc: +Signed-off-by: Boris Brezillon +Co-developed-by: Dmitry Osipenko +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index bd5a0073009d..4a0b4bf03f1a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -502,11 +502,18 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + mapping_set_unevictable(mapping); + + for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) { ++ /* Can happen if the last fault only partially filled this ++ * section of the pages array before failing. In that case ++ * we skip already filled pages. ++ */ ++ if (pages[i]) ++ continue; ++ + pages[i] = shmem_read_mapping_page(mapping, i); + if (IS_ERR(pages[i])) { + ret = PTR_ERR(pages[i]); + pages[i] = NULL; +- goto err_pages; ++ goto err_unlock; + } + } + +@@ -514,7 +521,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + ret = sg_alloc_table_from_pages(sgt, pages + page_offset, + NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL); + if (ret) +- goto err_pages; ++ goto err_unlock; + + ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0); + if (ret) +@@ -537,8 +544,6 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + + err_map: + sg_free_table(sgt); +-err_pages: +- drm_gem_shmem_put_pages_locked(&bo->base); + err_unlock: + dma_resv_unlock(obj->resv); + err_bo: +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (16 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 19/30] drm/virtio: " Dmitry Osipenko + ` (11 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +To simplify the drm-shmem refcnt handling, we're moving away from +the implicit get_pages() that is used by get_pages_sgt(). From now on +drivers will have to pin pages while they use sgt. Panfrost's shrinker +doesn't support swapping out BOs, hence pages are pinned and sgt is valid +as long as pages' use-count > 0. + +In Panfrost, panfrost_gem_mapping, which is the object representing a +GPU mapping of a BO, owns a pages ref. This guarantees that any BO being +mapped GPU side has its pages retained till the mapping is destroyed. + +Since pages are no longer guaranteed to stay pinned for the BO lifetime, +and MADVISE(DONT_NEED) flagging remains after the GEM handle has been +destroyed, we need to add an extra 'is_purgeable' check in +panfrost_gem_purge(), to make sure we're not trying to purge a BO that +already had its pages released. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/panfrost/panfrost_gem.c | 63 ++++++++++++++----- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 6 ++ + 2 files changed, 52 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index f268bd5c2884..7edfc12f7c1f 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -35,20 +35,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) + */ + WARN_ON_ONCE(!list_empty(&bo->mappings.list)); + +- if (bo->sgts) { +- int i; +- int n_sgt = bo->base.base.size / SZ_2M; +- +- for (i = 0; i < n_sgt; i++) { +- if (bo->sgts[i].sgl) { +- dma_unmap_sgtable(pfdev->dev, &bo->sgts[i], +- DMA_BIDIRECTIONAL, 0); +- sg_free_table(&bo->sgts[i]); +- } +- } +- kvfree(bo->sgts); +- } +- + drm_gem_shmem_free(&bo->base); + } + +@@ -85,11 +71,40 @@ panfrost_gem_teardown_mapping(struct panfrost_gem_mapping *mapping) + + static void panfrost_gem_mapping_release(struct kref *kref) + { +- struct panfrost_gem_mapping *mapping; +- +- mapping = container_of(kref, struct panfrost_gem_mapping, refcount); ++ struct panfrost_gem_mapping *mapping = ++ container_of(kref, struct panfrost_gem_mapping, refcount); ++ struct panfrost_gem_object *bo = mapping->obj; ++ struct panfrost_device *pfdev = bo->base.base.dev->dev_private; + + panfrost_gem_teardown_mapping(mapping); ++ ++ /* On heap BOs, release the sgts created in the fault handler path. */ ++ if (bo->sgts) { ++ int i, n_sgt = bo->base.base.size / SZ_2M; ++ ++ for (i = 0; i < n_sgt; i++) { ++ if (bo->sgts[i].sgl) { ++ dma_unmap_sgtable(pfdev->dev, &bo->sgts[i], ++ DMA_BIDIRECTIONAL, 0); ++ sg_free_table(&bo->sgts[i]); ++ } ++ } ++ kvfree(bo->sgts); ++ } ++ ++ /* Pages ref is owned by the panfrost_gem_mapping object. We must ++ * release our pages ref (if any), before releasing the object ++ * ref. ++ * Non-heap BOs acquired the pages at panfrost_gem_mapping creation ++ * time, and heap BOs may have acquired pages if the fault handler ++ * was called, in which case bo->sgts should be non-NULL. ++ */ ++ if (!bo->base.base.import_attach && (!bo->is_heap || bo->sgts) && ++ bo->base.madv >= 0) { ++ drm_gem_shmem_put_pages(&bo->base); ++ bo->sgts = NULL; ++ } ++ + drm_gem_object_put(&mapping->obj->base.base); + panfrost_mmu_ctx_put(mapping->mmu); + kfree(mapping); +@@ -125,6 +140,20 @@ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) + if (!mapping) + return -ENOMEM; + ++ if (!bo->is_heap && !bo->base.base.import_attach) { ++ /* Pages ref is owned by the panfrost_gem_mapping object. ++ * For non-heap BOs, we request pages at mapping creation ++ * time, such that the panfrost_mmu_map() call, further down in ++ * this function, is guaranteed to have pages_use_count > 0 ++ * when drm_gem_shmem_get_pages_sgt() is called. ++ */ ++ ret = drm_gem_shmem_get_pages(&bo->base); ++ if (ret) { ++ kfree(mapping); ++ return ret; ++ } ++ } ++ + INIT_LIST_HEAD(&mapping->node); + kref_init(&mapping->refcount); + drm_gem_object_get(obj); +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +index 02b60ea1433a..d4fb0854cf2f 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +@@ -50,6 +50,12 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) + if (!dma_resv_trylock(shmem->base.resv)) + goto unlock_mappings; + ++ /* BO might have become unpurgeable if the last pages_use_count ref ++ * was dropped, but the BO hasn't been destroyed yet. ++ */ ++ if (!drm_gem_shmem_is_purgeable(shmem)) ++ goto unlock_mappings; ++ + panfrost_gem_teardown_mappings_locked(bo); + drm_gem_shmem_purge_locked(&bo->base); + ret = true; +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 19/30] drm/virtio: Explicitly get and put drm-shmem pages + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (17 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 20/30] drm/v3d: " Dmitry Osipenko + ` (10 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +We're moving away from implicit get_pages() that is done by +get_pages_sgt() to simplify the refcnt handling. Drivers will have +to pin pages while they use sgt. VirtIO-GPU doesn't support shrinker, +hence pages are pinned and sgt is valid as long as pages' use-count > 0. + +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_object.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index c7e74cf13022..e58528c562ef 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -67,6 +67,7 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) + + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); + if (virtio_gpu_is_shmem(bo)) { ++ drm_gem_shmem_put_pages(&bo->base); + drm_gem_shmem_free(&bo->base); + } else if (virtio_gpu_is_vram(bo)) { + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); +@@ -196,9 +197,13 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + return PTR_ERR(shmem_obj); + bo = gem_to_virtio_gpu_obj(&shmem_obj->base); + ++ ret = drm_gem_shmem_get_pages(shmem_obj); ++ if (ret) ++ goto err_free_gem; ++ + ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle); + if (ret < 0) +- goto err_free_gem; ++ goto err_put_pages; + + bo->dumb = params->dumb; + +@@ -243,6 +248,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + kvfree(ents); + err_put_id: + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); ++err_put_pages: ++ drm_gem_shmem_put_pages(shmem_obj); + err_free_gem: + drm_gem_shmem_free(shmem_obj); + return ret; +-- +2.43.0 + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 21/30] drm/shmem-helper: Change sgt allocation policy + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (19 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 20/30] drm/v3d: " Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker Dmitry Osipenko + ` (8 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +In a preparation to addition of drm-shmem memory shrinker support, change +the SGT allocation policy in this way: + +1. SGT can be allocated only if shmem pages are pinned at the +time of allocation, otherwise allocation fails. + +2. Drivers must ensure that pages are pinned during the time of SGT usage +and should get new SGT if pages were unpinned. + +This new policy is required by the shrinker because it will move pages +to/from SWAP unless pages are pinned, invalidating SGT pointer once pages +are relocated. + +Previous patches prepared drivers to the new policy. + +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 55 ++++++++++++++------------ + 1 file changed, 29 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index c7357110ca76..ff5437ab2c95 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -133,6 +133,14 @@ drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + ++ if (shmem->sgt) { ++ dma_unmap_sgtable(obj->dev->dev, shmem->sgt, ++ DMA_BIDIRECTIONAL, 0); ++ sg_free_table(shmem->sgt); ++ kfree(shmem->sgt); ++ shmem->sgt = NULL; ++ } ++ + #ifdef CONFIG_X86 + if (shmem->map_wc) + set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); +@@ -155,24 +163,12 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + +- if (obj->import_attach) { ++ if (obj->import_attach) + drm_prime_gem_destroy(obj, shmem->sgt); +- } else { +- drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); + +- if (shmem->sgt) { +- dma_unmap_sgtable(obj->dev->dev, shmem->sgt, +- DMA_BIDIRECTIONAL, 0); +- sg_free_table(shmem->sgt); +- kfree(shmem->sgt); +- } +- if (shmem->pages && +- refcount_dec_and_test(&shmem->pages_use_count)) +- drm_gem_shmem_free_pages(shmem); +- +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); +- } ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); + + drm_gem_object_release(obj); + kfree(shmem); +@@ -722,6 +718,9 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) + + drm_WARN_ON(obj->dev, obj->import_attach); + ++ if (drm_WARN_ON(obj->dev, !shmem->pages)) ++ return ERR_PTR(-ENOMEM); ++ + return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); +@@ -737,15 +736,10 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + + drm_WARN_ON(obj->dev, obj->import_attach); + +- ret = drm_gem_shmem_get_pages_locked(shmem); +- if (ret) +- return ERR_PTR(ret); +- + sgt = drm_gem_shmem_get_sg_table(shmem); +- if (IS_ERR(sgt)) { +- ret = PTR_ERR(sgt); +- goto err_put_pages; +- } ++ if (IS_ERR(sgt)) ++ return sgt; ++ + /* Map the pages for use by the h/w. */ + ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0); + if (ret) +@@ -758,8 +752,6 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + err_free_sgt: + sg_free_table(sgt); + kfree(sgt); +-err_put_pages: +- drm_gem_shmem_put_pages_locked(shmem); + return ERR_PTR(ret); + } + +@@ -776,6 +768,17 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + * and difference between dma-buf imported and natively allocated objects. + * drm_gem_shmem_get_sg_table() should not be directly called by drivers. + * ++ * Drivers should adhere to these SGT usage rules: ++ * ++ * 1. SGT should be allocated only if shmem pages are pinned at the ++ * time of allocation, otherwise allocation will fail. ++ * ++ * 2. Drivers should ensure that pages are pinned during the time of ++ * SGT usage and should get new SGT if pages were unpinned. ++ * ++ * Drivers don't own returned SGT and must take care of the SGT pointer ++ * lifetime. SGT is valid as long as GEM pages that backing SGT are pinned. ++ * + * Returns: + * A pointer to the scatter/gather table of pinned pages or errno on failure. + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (20 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 21/30] drm/shmem-helper: Change sgt allocation policy Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() Dmitry Osipenko + ` (7 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Introduce common drm-shmem shrinker for DRM drivers. + +To start using drm-shmem shrinker drivers should do the following: + +1. Implement evict() callback of GEM object where driver should check + whether object is purgeable or evictable using drm-shmem helpers and + perform the shrinking action + +2. Initialize drm-shmem internals using drmm_gem_shmem_init(drm_device), + which will register drm-shmem shrinker + +3. Implement madvise IOCTL that will use drm_gem_shmem_madvise() + +Signed-off-by: Daniel Almeida +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 365 +++++++++++++++++- + drivers/gpu/drm/panfrost/panfrost_gem.c | 3 +- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 13 +- + include/drm/drm_device.h | 10 +- + include/drm/drm_gem_shmem_helper.h | 68 +++- + 5 files changed, 433 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index ff5437ab2c95..59cebd1e35af 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -128,11 +129,49 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_create); + ++static bool drm_gem_shmem_is_evictable(struct drm_gem_shmem_object *shmem) ++{ ++ return (shmem->madv >= 0) && shmem->base.funcs->evict && ++ refcount_read(&shmem->pages_use_count) && ++ !refcount_read(&shmem->pages_pin_count) && ++ !shmem->base.dma_buf && !shmem->base.import_attach && ++ !shmem->evicted; ++} ++ ++static void ++drm_gem_shmem_shrinker_update_lru_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ struct drm_gem_shmem *shmem_mm = obj->dev->shmem_mm; ++ struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker; ++ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (!shmem_shrinker || obj->import_attach) ++ return; ++ ++ if (shmem->madv < 0) ++ drm_gem_lru_remove(&shmem->base); ++ else if (drm_gem_shmem_is_evictable(shmem) || drm_gem_shmem_is_purgeable(shmem)) ++ drm_gem_lru_move_tail(&shmem_shrinker->lru_evictable, &shmem->base); ++ else if (shmem->evicted) ++ drm_gem_lru_move_tail(&shmem_shrinker->lru_evicted, &shmem->base); ++ else if (!shmem->pages) ++ drm_gem_lru_remove(&shmem->base); ++ else ++ drm_gem_lru_move_tail(&shmem_shrinker->lru_pinned, &shmem->base); ++} ++ + static void + drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + ++ if (!shmem->pages) { ++ drm_WARN_ON(obj->dev, !shmem->evicted && shmem->madv >= 0); ++ return; ++ } ++ + if (shmem->sgt) { + dma_unmap_sgtable(obj->dev->dev, shmem->sgt, + DMA_BIDIRECTIONAL, 0); +@@ -175,15 +214,26 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_free); + +-static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) ++static int ++drm_gem_shmem_acquire_pages(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + struct page **pages; + ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return -EINVAL; ++ + dma_resv_assert_held(shmem->base.resv); + +- if (refcount_inc_not_zero(&shmem->pages_use_count)) ++ if (shmem->madv < 0) { ++ drm_WARN_ON(obj->dev, shmem->pages); ++ return -ENOMEM; ++ } ++ ++ if (shmem->pages) { ++ drm_WARN_ON(obj->dev, !shmem->evicted); + return 0; ++ } + + pages = drm_gem_get_pages(obj); + if (IS_ERR(pages)) { +@@ -204,8 +254,29 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) + + shmem->pages = pages; + ++ return 0; ++} ++ ++static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) ++{ ++ int err; ++ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (shmem->madv < 0) ++ return -ENOMEM; ++ ++ if (refcount_inc_not_zero(&shmem->pages_use_count)) ++ return 0; ++ ++ err = drm_gem_shmem_acquire_pages(shmem); ++ if (err) ++ return err; ++ + refcount_set(&shmem->pages_use_count, 1); + ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++ + return 0; + } + +@@ -222,6 +293,8 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) + + if (refcount_dec_and_test(&shmem->pages_use_count)) + drm_gem_shmem_free_pages(shmem); ++ ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); + +@@ -266,6 +339,11 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages); + * + * This function Increases the use count and allocates the backing pages if + * use-count equals to zero. ++ * ++ * Note that this function doesn't pin pages in memory. If your driver ++ * uses drm-shmem shrinker, then it's free to relocate pages to swap. ++ * Getting pages only guarantees that pages are allocated, and not that ++ * pages reside in memory. In order to pin pages use drm_gem_shmem_pin(). + */ + int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem) + { +@@ -291,6 +369,10 @@ static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) + if (refcount_inc_not_zero(&shmem->pages_pin_count)) + return 0; + ++ ret = drm_gem_shmem_swapin_locked(shmem); ++ if (ret) ++ return ret; ++ + ret = drm_gem_shmem_get_pages_locked(shmem); + if (!ret) + refcount_set(&shmem->pages_pin_count, 1); +@@ -489,29 +571,48 @@ int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv) + + madv = shmem->madv; + ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++ + return (madv >= 0); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked); + +-void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) ++int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) + { + struct drm_gem_object *obj = &shmem->base; +- struct drm_device *dev = obj->dev; ++ int ret; + +- dma_resv_assert_held(shmem->base.resv); ++ ret = dma_resv_lock_interruptible(obj->resv, NULL); ++ if (ret) ++ return ret; + +- drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem)); ++ ret = drm_gem_shmem_madvise_locked(shmem, madv); ++ dma_resv_unlock(obj->resv); + +- dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0); +- sg_free_table(shmem->sgt); +- kfree(shmem->sgt); +- shmem->sgt = NULL; ++ return ret; ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise); + +- drm_gem_shmem_put_pages_locked(shmem); ++static void ++drm_gem_shmem_shrinker_put_pages_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ struct drm_device *dev = obj->dev; + +- shmem->madv = -1; ++ dma_resv_assert_held(shmem->base.resv); + ++ if (shmem->evicted) ++ return; ++ ++ drm_gem_shmem_free_pages(shmem); + drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping); ++} ++ ++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ ++ drm_gem_shmem_shrinker_put_pages_locked(shmem); + drm_gem_free_mmap_offset(obj); + + /* Our goal here is to return as much of the memory as +@@ -522,9 +623,45 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) + shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1); + + invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); ++ ++ shmem->madv = -1; ++ shmem->evicted = false; ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked); + ++/** ++ * drm_gem_shmem_swapin_locked() - Moves shmem GEM back to memory and enables ++ * hardware access to the memory. ++ * @shmem: shmem GEM object ++ * ++ * This function moves shmem GEM back to memory if it was previously evicted ++ * by the memory shrinker. The GEM is ready to use on success. ++ * ++ * Returns: ++ * 0 on success or a negative error code on failure. ++ */ ++int drm_gem_shmem_swapin_locked(struct drm_gem_shmem_object *shmem) ++{ ++ int err; ++ ++ dma_resv_assert_held(shmem->base.resv); ++ ++ if (!shmem->evicted) ++ return 0; ++ ++ err = drm_gem_shmem_acquire_pages(shmem); ++ if (err) ++ return err; ++ ++ shmem->evicted = false; ++ ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_swapin_locked); ++ + /** + * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object + * @file: DRM file structure to create the dumb buffer for +@@ -571,22 +708,32 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) + vm_fault_t ret; + struct page *page; + pgoff_t page_offset; ++ int err; + + /* We don't use vmf->pgoff since that has the fake offset */ + page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; + + dma_resv_lock(shmem->base.resv, NULL); + +- if (page_offset >= num_pages || +- drm_WARN_ON_ONCE(obj->dev, !shmem->pages) || +- shmem->madv < 0) { ++ err = drm_gem_shmem_swapin_locked(shmem); ++ if (err) { ++ ret = VM_FAULT_OOM; ++ goto unlock; ++ } ++ ++ if (page_offset >= num_pages || !shmem->pages) { + ret = VM_FAULT_SIGBUS; + } else { ++ /* ++ * shmem->pages is guaranteed to be valid while reservation ++ * lock is held and drm_gem_shmem_swapin_locked() succeeds. ++ */ + page = shmem->pages[page_offset]; + + ret = vmf_insert_pfn(vma, vmf->address, page_to_pfn(page)); + } + ++unlock: + dma_resv_unlock(shmem->base.resv); + + return ret; +@@ -609,6 +756,7 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) + drm_WARN_ON_ONCE(obj->dev, + !refcount_inc_not_zero(&shmem->pages_use_count)); + ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); + dma_resv_unlock(shmem->base.resv); + + drm_gem_vm_open(vma); +@@ -694,7 +842,9 @@ void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); + drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); + drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count)); ++ drm_printf_indent(p, indent, "evicted=%d\n", shmem->evicted); + drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); ++ drm_printf_indent(p, indent, "madv=%d\n", shmem->madv); + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); + +@@ -784,8 +934,13 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + */ + struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) + { +- int ret; ++ struct drm_gem_object *obj = &shmem->base; + struct sg_table *sgt; ++ int ret; ++ ++ if (drm_WARN_ON(obj->dev, drm_gem_shmem_is_evictable(shmem)) || ++ drm_WARN_ON(obj->dev, drm_gem_shmem_is_purgeable(shmem))) ++ return ERR_PTR(-EBUSY); + + ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); + if (ret) +@@ -832,6 +987,184 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table); + ++static unsigned long ++drm_gem_shmem_shrinker_count_objects(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = shrinker->private_data; ++ unsigned long count = shmem_shrinker->lru_evictable.count; ++ ++ if (count >= SHRINK_EMPTY) ++ return SHRINK_EMPTY - 1; ++ ++ return count ?: SHRINK_EMPTY; ++} ++ ++void drm_gem_shmem_evict_locked(struct drm_gem_shmem_object *shmem) ++{ ++ struct drm_gem_object *obj = &shmem->base; ++ ++ drm_WARN_ON(obj->dev, !drm_gem_shmem_is_evictable(shmem)); ++ drm_WARN_ON(obj->dev, shmem->evicted); ++ ++ drm_gem_shmem_shrinker_put_pages_locked(shmem); ++ ++ shmem->evicted = true; ++ drm_gem_shmem_shrinker_update_lru_locked(shmem); ++} ++EXPORT_SYMBOL_GPL(drm_gem_shmem_evict_locked); ++ ++static bool drm_gem_shmem_shrinker_evict_locked(struct drm_gem_object *obj) ++{ ++ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); ++ int err; ++ ++ if (!drm_gem_shmem_is_evictable(shmem) || ++ get_nr_swap_pages() < obj->size >> PAGE_SHIFT) ++ return false; ++ ++ err = drm_gem_evict_locked(obj); ++ if (err) ++ return false; ++ ++ return true; ++} ++ ++static bool drm_gem_shmem_shrinker_purge_locked(struct drm_gem_object *obj) ++{ ++ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); ++ int err; ++ ++ if (!drm_gem_shmem_is_purgeable(shmem)) ++ return false; ++ ++ err = drm_gem_evict_locked(obj); ++ if (err) ++ return false; ++ ++ return true; ++} ++ ++static unsigned long ++drm_gem_shmem_shrinker_scan_objects(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = shrinker->private_data; ++ unsigned long nr_to_scan = sc->nr_to_scan; ++ unsigned long remaining = 0; ++ unsigned long freed = 0; ++ ++ /* purge as many objects as we can */ ++ freed += drm_gem_lru_scan(&shmem_shrinker->lru_evictable, ++ nr_to_scan, &remaining, ++ drm_gem_shmem_shrinker_purge_locked); ++ ++ /* evict as many objects as we can */ ++ if (freed < nr_to_scan) ++ freed += drm_gem_lru_scan(&shmem_shrinker->lru_evictable, ++ nr_to_scan - freed, &remaining, ++ drm_gem_shmem_shrinker_evict_locked); ++ ++ return (freed > 0 && remaining > 0) ? freed : SHRINK_STOP; ++} ++ ++static int drm_gem_shmem_shrinker_init(struct drm_gem_shmem *shmem_mm, ++ const char *shrinker_name) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker; ++ struct shrinker *shrinker; ++ ++ shrinker = shrinker_alloc(0, shrinker_name); ++ if (!shrinker) ++ return -ENOMEM; ++ ++ shrinker->count_objects = drm_gem_shmem_shrinker_count_objects; ++ shrinker->scan_objects = drm_gem_shmem_shrinker_scan_objects; ++ shrinker->private_data = shmem_shrinker; ++ shrinker->seeks = DEFAULT_SEEKS; ++ ++ mutex_init(&shmem_shrinker->lock); ++ shmem_shrinker->shrinker = shrinker; ++ drm_gem_lru_init(&shmem_shrinker->lru_evictable, &shmem_shrinker->lock); ++ drm_gem_lru_init(&shmem_shrinker->lru_evicted, &shmem_shrinker->lock); ++ drm_gem_lru_init(&shmem_shrinker->lru_pinned, &shmem_shrinker->lock); ++ ++ shrinker_register(shrinker); ++ ++ return 0; ++} ++ ++static void drm_gem_shmem_shrinker_release(struct drm_device *dev, ++ struct drm_gem_shmem *shmem_mm) ++{ ++ struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker; ++ ++ shrinker_free(shmem_shrinker->shrinker); ++ drm_WARN_ON(dev, !list_empty(&shmem_shrinker->lru_evictable.list)); ++ drm_WARN_ON(dev, !list_empty(&shmem_shrinker->lru_evicted.list)); ++ drm_WARN_ON(dev, !list_empty(&shmem_shrinker->lru_pinned.list)); ++ mutex_destroy(&shmem_shrinker->lock); ++} ++ ++static int drm_gem_shmem_init(struct drm_device *dev) ++{ ++ int err; ++ ++ if (drm_WARN_ON(dev, dev->shmem_mm)) ++ return -EBUSY; ++ ++ dev->shmem_mm = kzalloc(sizeof(*dev->shmem_mm), GFP_KERNEL); ++ if (!dev->shmem_mm) ++ return -ENOMEM; ++ ++ err = drm_gem_shmem_shrinker_init(dev->shmem_mm, dev->unique); ++ if (err) ++ goto free_gem_shmem; ++ ++ return 0; ++ ++free_gem_shmem: ++ kfree(dev->shmem_mm); ++ dev->shmem_mm = NULL; ++ ++ return err; ++} ++ ++static void drm_gem_shmem_release(struct drm_device *dev, void *ptr) ++{ ++ struct drm_gem_shmem *shmem_mm = dev->shmem_mm; ++ ++ drm_gem_shmem_shrinker_release(dev, shmem_mm); ++ dev->shmem_mm = NULL; ++ kfree(shmem_mm); ++} ++ ++/** ++ * drmm_gem_shmem_init() - Initialize drm-shmem internals ++ * @dev: DRM device ++ * ++ * Cleanup is automatically managed as part of DRM device releasing. ++ * Calling this function multiple times will result in a error. ++ * ++ * Returns: ++ * 0 on success or a negative error code on failure. ++ */ ++int drmm_gem_shmem_init(struct drm_device *dev) ++{ ++ int err; ++ ++ err = drm_gem_shmem_init(dev); ++ if (err) ++ return err; ++ ++ err = drmm_add_action_or_reset(dev, drm_gem_shmem_release, NULL); ++ if (err) ++ return err; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(drmm_gem_shmem_init); ++ + MODULE_DESCRIPTION("DRM SHMEM memory-management helpers"); + MODULE_IMPORT_NS(DMA_BUF); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index 7edfc12f7c1f..8c26b7e41b95 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -99,8 +99,7 @@ static void panfrost_gem_mapping_release(struct kref *kref) + * time, and heap BOs may have acquired pages if the fault handler + * was called, in which case bo->sgts should be non-NULL. + */ +- if (!bo->base.base.import_attach && (!bo->is_heap || bo->sgts) && +- bo->base.madv >= 0) { ++ if (!bo->base.base.import_attach && (!bo->is_heap || bo->sgts)) { + drm_gem_shmem_put_pages(&bo->base); + bo->sgts = NULL; + } +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +index d4fb0854cf2f..7b4deba803ed 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +@@ -15,6 +15,13 @@ + #include "panfrost_gem.h" + #include "panfrost_mmu.h" + ++static bool panfrost_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) ++{ ++ return (shmem->madv > 0) && ++ !refcount_read(&shmem->pages_pin_count) && shmem->sgt && ++ !shmem->base.dma_buf && !shmem->base.import_attach; ++} ++ + static unsigned long + panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) + { +@@ -26,7 +33,7 @@ panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc + return 0; + + list_for_each_entry(shmem, &pfdev->shrinker_list, madv_list) { +- if (drm_gem_shmem_is_purgeable(shmem)) ++ if (panfrost_gem_shmem_is_purgeable(shmem)) + count += shmem->base.size >> PAGE_SHIFT; + } + +@@ -53,7 +60,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) + /* BO might have become unpurgeable if the last pages_use_count ref + * was dropped, but the BO hasn't been destroyed yet. + */ +- if (!drm_gem_shmem_is_purgeable(shmem)) ++ if (!panfrost_gem_shmem_is_purgeable(shmem)) + goto unlock_mappings; + + panfrost_gem_teardown_mappings_locked(bo); +@@ -80,7 +87,7 @@ panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) + list_for_each_entry_safe(shmem, tmp, &pfdev->shrinker_list, madv_list) { + if (freed >= sc->nr_to_scan) + break; +- if (drm_gem_shmem_is_purgeable(shmem) && ++ if (panfrost_gem_shmem_is_purgeable(shmem) && + panfrost_gem_purge(&shmem->base)) { + freed += shmem->base.size >> PAGE_SHIFT; + list_del_init(&shmem->madv_list); +diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h +index 63767cf24371..6e729e716505 100644 +--- a/include/drm/drm_device.h ++++ b/include/drm/drm_device.h +@@ -15,6 +15,7 @@ struct drm_vblank_crtc; + struct drm_vma_offset_manager; + struct drm_vram_mm; + struct drm_fb_helper; ++struct drm_gem_shmem_shrinker; + + struct inode; + +@@ -289,8 +290,13 @@ struct drm_device { + /** @vma_offset_manager: GEM information */ + struct drm_vma_offset_manager *vma_offset_manager; + +- /** @vram_mm: VRAM MM memory manager */ +- struct drm_vram_mm *vram_mm; ++ union { ++ /** @vram_mm: VRAM MM memory manager */ ++ struct drm_vram_mm *vram_mm; ++ ++ /** @shmem_mm: SHMEM GEM memory manager */ ++ struct drm_gem_shmem *shmem_mm; ++ }; + + /** + * @switch_power_state: +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 525480488451..df97c11fc99a 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -13,6 +14,7 @@ + #include + + struct dma_buf_attachment; ++struct drm_device; + struct drm_mode_create_dumb; + struct drm_printer; + struct sg_table; +@@ -54,8 +56,8 @@ struct drm_gem_shmem_object { + * @madv: State for madvise + * + * 0 is active/inuse. ++ * 1 is not-needed/can-be-purged + * A negative value is the object is purged. +- * Positive values are driver specific and not used by the helpers. + */ + int madv; + +@@ -102,6 +104,14 @@ struct drm_gem_shmem_object { + * @map_wc: map object write-combined (instead of using shmem defaults). + */ + bool map_wc : 1; ++ ++ /** ++ * @evicted: True if shmem pages are evicted by the memory shrinker. ++ * Used internally by memory shrinker. The evicted pages can be ++ * moved back to memory using drm_gem_shmem_swapin_locked(), unlike ++ * the purged pages (madv < 0) that are destroyed permanently. ++ */ ++ bool evicted : 1; + }; + + #define to_drm_gem_shmem_obj(obj) \ +@@ -122,14 +132,19 @@ void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, + int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma); + + int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv); ++int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv); + + static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) + { +- return (shmem->madv > 0) && +- !refcount_read(&shmem->pages_pin_count) && shmem->sgt && ++ return (shmem->madv > 0) && shmem->base.funcs->evict && ++ refcount_read(&shmem->pages_use_count) && ++ !refcount_read(&shmem->pages_pin_count) && + !shmem->base.dma_buf && !shmem->base.import_attach; + } + ++int drm_gem_shmem_swapin_locked(struct drm_gem_shmem_object *shmem); ++ ++void drm_gem_shmem_evict_locked(struct drm_gem_shmem_object *shmem); + void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem); + + struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem); +@@ -273,6 +288,53 @@ static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct v + return drm_gem_shmem_mmap(shmem, vma); + } + ++/** ++ * drm_gem_shmem_object_madvise - unlocked GEM object function for drm_gem_shmem_madvise_locked() ++ * @obj: GEM object ++ * @madv: Madvise value ++ * ++ * This function wraps drm_gem_shmem_madvise_locked(), providing unlocked variant. ++ * ++ * Returns: ++ * 0 on success or a negative error code on failure. ++ */ ++static inline int drm_gem_shmem_object_madvise(struct drm_gem_object *obj, int madv) ++{ ++ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); ++ ++ return drm_gem_shmem_madvise(shmem, madv); ++} ++ ++/** ++ * struct drm_gem_shmem_shrinker - Memory shrinker of GEM shmem memory manager ++ */ ++struct drm_gem_shmem_shrinker { ++ /** @lock: Protects @lru_* */ ++ struct mutex lock; ++ ++ /** @shrinker: Shrinker for purging shmem GEM objects */ ++ struct shrinker *shrinker; ++ ++ /** @lru_pinned: List of pinned shmem GEM objects */ ++ struct drm_gem_lru lru_pinned; ++ ++ /** @lru_evictable: List of shmem GEM objects to be evicted */ ++ struct drm_gem_lru lru_evictable; ++ ++ /** @lru_evicted: List of evicted shmem GEM objects */ ++ struct drm_gem_lru lru_evicted; ++}; ++ ++/** ++ * struct drm_gem_shmem - GEM shmem memory manager ++ */ ++struct drm_gem_shmem { ++ /** @shrinker: GEM shmem shrinker */ ++ struct drm_gem_shmem_shrinker shrinker; ++}; ++ ++int drmm_gem_shmem_init(struct drm_device *dev); ++ + /* + * Driver ops + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (21 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() Dmitry Osipenko + ` (6 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Export drm_gem_shmem_get_pages_sgt_locked() that will be used by virtio-gpu +shrinker during GEM swap-in operation done under the held reservation lock. + +Reviewed-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +++++++++++++++++++++- + include/drm/drm_gem_shmem_helper.h | 1 + + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 59cebd1e35af..8fd7851c088b 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -875,12 +875,31 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); + +-static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) ++/** ++ * drm_gem_shmem_get_pages_sgt_locked - Provide a scatter/gather table of pinned ++ * pages for a shmem GEM object ++ * @shmem: shmem GEM object ++ * ++ * This is a locked version of @drm_gem_shmem_get_sg_table that exports a ++ * scatter/gather table suitable for PRIME usage by calling the standard ++ * DMA mapping API. ++ * ++ * Drivers must hold GEM's reservation lock when using this function. ++ * ++ * Drivers who need to acquire an scatter/gather table for objects need to call ++ * drm_gem_shmem_get_pages_sgt() instead. ++ * ++ * Returns: ++ * A pointer to the scatter/gather table of pinned pages or error pointer on failure. ++ */ ++struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + int ret; + struct sg_table *sgt; + ++ dma_resv_assert_held(shmem->base.resv); ++ + if (shmem->sgt) + return shmem->sgt; + +@@ -904,6 +923,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ + kfree(sgt); + return ERR_PTR(ret); + } ++EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt_locked); + + /** + * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index df97c11fc99a..167f00f089de 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -149,6 +149,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem); + + struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem); + struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem); ++struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem); + + void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, + struct drm_printer *p, unsigned int indent); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (22 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM Dmitry Osipenko + ` (5 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +SGT isn't refcounted. Once SGT pointer has been obtained, it remains the +same for both locked and unlocked get_pages_sgt(). Return cached SGT +directly without taking a potentially expensive lock. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 8fd7851c088b..e6e6e693ab95 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -962,6 +962,18 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) + drm_WARN_ON(obj->dev, drm_gem_shmem_is_purgeable(shmem))) + return ERR_PTR(-EBUSY); + ++ /* ++ * Drivers that use shrinker should take into account that shrinker ++ * may relocate BO, thus invalidating the returned SGT pointer. ++ * Such drivers should pin GEM while they use SGT. ++ * ++ * Drivers that don't use shrinker should take into account that ++ * SGT is released together with the GEM pages. Pages should be kept ++ * alive while SGT is used. ++ */ ++ if (shmem->sgt) ++ return shmem->sgt; ++ + ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); + if (ret) + return ERR_PTR(ret); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (23 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors Dmitry Osipenko + ` (4 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Don't free shmem object if it has pages that are in use at the time of +the GEM's freeing if DRM driver doesn't manage GEM/pages lifetime properly. +This prevents memory corruption due to the use-after-free bug in exchange +to leaking GEM. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index e6e6e693ab95..0d95d723b90d 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -205,9 +205,15 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) + if (obj->import_attach) + drm_prime_gem_destroy(obj, shmem->sgt); + +- drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); +- drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); ++ /* ++ * Prevent memory corruption caused by the use-after-free bug in a ++ * case where shmem user erroneously holds reference to pages while ++ * GEM is freed by leaking the GEM. ++ */ ++ if (drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)) || ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)) || ++ drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count))) ++ return; + + drm_gem_object_release(obj); + kfree(shmem); +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (24 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO Dmitry Osipenko + ` (3 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Turn sanity warnings about DRM-SHMEM API misuse into a error conditions +for cases where imported GEM is used when it shouldn't be used. + +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 0d95d723b90d..7d2fe12bd793 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -409,7 +409,8 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) + struct drm_gem_object *obj = &shmem->base; + int ret; + +- drm_WARN_ON(obj->dev, obj->import_attach); ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return -EINVAL; + + if (refcount_inc_not_zero(&shmem->pages_pin_count)) + return 0; +@@ -872,7 +873,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + +- drm_WARN_ON(obj->dev, obj->import_attach); ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return ERR_PTR(-EINVAL); + + if (drm_WARN_ON(obj->dev, !shmem->pages)) + return ERR_PTR(-ENOMEM); +@@ -909,7 +911,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object + if (shmem->sgt) + return shmem->sgt; + +- drm_WARN_ON(obj->dev, obj->import_attach); ++ if (drm_WARN_ON(obj->dev, obj->import_attach)) ++ return ERR_PTR(-EINVAL); + + sgt = drm_gem_shmem_get_sg_table(shmem); + if (IS_ERR(sgt)) +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (25 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically Dmitry Osipenko + ` (2 subsequent siblings) + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Prepare to addition of memory shrinker support by pinning display +framebuffer BO pages in memory while they are in use by display on host. +Shrinker is free to relocate framebuffer BO pages if it doesn't know that +pages are in use, thus pin the pages to disallow shrinker to move them. + +Acked-by: Gerd Hoffmann +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++ + drivers/gpu/drm/virtio/virtgpu_gem.c | 19 +++++++++++++++++++ + drivers/gpu/drm/virtio/virtgpu_plane.c | 17 +++++++++++++++-- + 3 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index bb7d86a0c6a1..83d1e4622292 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -318,6 +318,8 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_work(struct work_struct *work); ++int virtio_gpu_gem_pin(struct virtio_gpu_object *bo); ++void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo); + + /* virtgpu_vq.c */ + int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); +diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c +index 7db48d17ee3a..625c05d625bf 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -294,3 +294,22 @@ void virtio_gpu_array_put_free_work(struct work_struct *work) + } + spin_unlock(&vgdev->obj_free_lock); + } ++ ++int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) ++{ ++ int err; ++ ++ if (virtio_gpu_is_shmem(bo)) { ++ err = drm_gem_shmem_pin(&bo->base); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo) ++{ ++ if (virtio_gpu_is_shmem(bo)) ++ drm_gem_shmem_unpin(&bo->base); ++} +diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c +index a72a2dbda031..162fb8a44d71 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_plane.c ++++ b/drivers/gpu/drm/virtio/virtgpu_plane.c +@@ -248,20 +248,28 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_object *bo; ++ int err; + + if (!new_state->fb) + return 0; + + vgfb = to_virtio_gpu_framebuffer(new_state->fb); + bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); +- if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) ++ ++ err = virtio_gpu_gem_pin(bo); ++ if (err) ++ return err; ++ ++ if (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob) + return 0; + + if (bo->dumb && (plane->state->fb != new_state->fb)) { + vgfb->fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, + 0); +- if (!vgfb->fence) ++ if (!vgfb->fence) { ++ virtio_gpu_gem_unpin(bo); + return -ENOMEM; ++ } + } + + return 0; +@@ -271,15 +279,20 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *state) + { + struct virtio_gpu_framebuffer *vgfb; ++ struct virtio_gpu_object *bo; + + if (!state->fb) + return; + + vgfb = to_virtio_gpu_framebuffer(state->fb); ++ bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); ++ + if (vgfb->fence) { + dma_fence_put(&vgfb->fence->f); + vgfb->fence = NULL; + } ++ ++ virtio_gpu_gem_unpin(bo); + } + + static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (26 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 29/30] drm/virtio: Support shmem shrinking Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker Dmitry Osipenko + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Prepare for addition of memory shrinker support by attaching shmem pages +to host dynamically on first use. Previously the attachment vq command +wasn't fenced and there was no vq kick made in the BO creation code path, +hence the attachment already was happening dynamically, but implicitly. +Making attachment explicitly dynamic will allow to simplify and reuse more +code when shrinker will be added. The virtio_gpu_object_shmem_init() now +works under the held reservation lock, which will be important to have for +shrinker to avoid moving pages while they are in active use by the driver. + +Acked-by: Gerd Hoffmann +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 7 +++ + drivers/gpu/drm/virtio/virtgpu_gem.c | 26 +++++++++ + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 32 +++++++---- + drivers/gpu/drm/virtio/virtgpu_object.c | 73 ++++++++++++++++++++----- + drivers/gpu/drm/virtio/virtgpu_submit.c | 15 ++++- + 5 files changed, 125 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index 83d1e4622292..1837dc7ea9fb 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -92,6 +92,7 @@ struct virtio_gpu_object { + uint32_t hw_res_handle; + bool dumb; + bool created; ++ bool detached; + bool host3d_blob, guest_blob; + uint32_t blob_mem, blob_flags; + +@@ -318,6 +319,8 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs); + void virtio_gpu_array_put_free_work(struct work_struct *work); ++int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object_array *objs); + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo); + void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo); + +@@ -458,6 +461,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + + bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); + ++int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo); ++ ++int virtio_gpu_reattach_shmem_object(struct virtio_gpu_object *bo); ++ + int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, + uint32_t *resid); + /* virtgpu_prime.c */ +diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c +index 625c05d625bf..97e67064c97e 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -295,6 +295,26 @@ void virtio_gpu_array_put_free_work(struct work_struct *work) + spin_unlock(&vgdev->obj_free_lock); + } + ++int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object_array *objs) ++{ ++ struct virtio_gpu_object *bo; ++ int ret = 0; ++ u32 i; ++ ++ for (i = 0; i < objs->nents; i++) { ++ bo = gem_to_virtio_gpu_obj(objs->objs[i]); ++ ++ if (virtio_gpu_is_shmem(bo) && bo->detached) { ++ ret = virtio_gpu_reattach_shmem_object_locked(bo); ++ if (ret) ++ break; ++ } ++ } ++ ++ return ret; ++} ++ + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) + { + int err; +@@ -303,6 +323,12 @@ int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) + err = drm_gem_shmem_pin(&bo->base); + if (err) + return err; ++ ++ err = virtio_gpu_reattach_shmem_object(bo); ++ if (err) { ++ drm_gem_shmem_unpin(&bo->base); ++ return err; ++ } + } + + return 0; +diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +index e4f76f315550..c7da22006149 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c ++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +@@ -256,6 +256,10 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, + if (ret != 0) + goto err_put_free; + ++ ret = virtio_gpu_array_prepare(vgdev, objs); ++ if (ret) ++ goto err_unlock; ++ + fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); + if (!fence) { + ret = -ENOMEM; +@@ -298,11 +302,25 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, + goto err_put_free; + } + ++ ret = virtio_gpu_array_lock_resv(objs); ++ if (ret != 0) ++ goto err_put_free; ++ ++ ret = virtio_gpu_array_prepare(vgdev, objs); ++ if (ret) ++ goto err_unlock; ++ ++ fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); ++ if (!fence) { ++ ret = -ENOMEM; ++ goto err_unlock; ++ } ++ + if (!vgdev->has_virgl_3d) { + virtio_gpu_cmd_transfer_to_host_2d + (vgdev, offset, + args->box.w, args->box.h, args->box.x, args->box.y, +- objs, NULL); ++ objs, fence); + } else { + virtio_gpu_create_context(dev, file); + +@@ -311,23 +329,13 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, + goto err_put_free; + } + +- ret = virtio_gpu_array_lock_resv(objs); +- if (ret != 0) +- goto err_put_free; +- +- ret = -ENOMEM; +- fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, +- 0); +- if (!fence) +- goto err_unlock; +- + virtio_gpu_cmd_transfer_to_host_3d + (vgdev, + vfpriv ? vfpriv->ctx_id : 0, offset, args->level, + args->stride, args->layer_stride, &args->box, objs, + fence); +- dma_fence_put(&fence->f); + } ++ dma_fence_put(&fence->f); + virtio_gpu_notify(vgdev); + return 0; + +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index e58528c562ef..de347aa3b9a8 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -143,7 +143,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, + struct sg_table *pages; + int si; + +- pages = drm_gem_shmem_get_pages_sgt(&bo->base); ++ pages = drm_gem_shmem_get_pages_sgt_locked(&bo->base); + if (IS_ERR(pages)) + return PTR_ERR(pages); + +@@ -177,6 +177,40 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, + return 0; + } + ++int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; ++ struct virtio_gpu_mem_entry *ents; ++ unsigned int nents; ++ int err; ++ ++ if (!bo->detached) ++ return 0; ++ ++ err = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); ++ if (err) ++ return err; ++ ++ virtio_gpu_object_attach(vgdev, bo, ents, nents); ++ ++ bo->detached = false; ++ ++ return 0; ++} ++ ++int virtio_gpu_reattach_shmem_object(struct virtio_gpu_object *bo) ++{ ++ int ret; ++ ++ ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL); ++ if (ret) ++ return ret; ++ ret = virtio_gpu_reattach_shmem_object_locked(bo); ++ dma_resv_unlock(bo->base.base.resv); ++ ++ return ret; ++} ++ + int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_params *params, + struct virtio_gpu_object **bo_ptr, +@@ -207,45 +241,56 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + + bo->dumb = params->dumb; + +- ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); +- if (ret != 0) +- goto err_put_id; ++ if (bo->blob_mem == VIRTGPU_BLOB_MEM_GUEST) ++ bo->guest_blob = true; + + if (fence) { + ret = -ENOMEM; + objs = virtio_gpu_array_alloc(1); + if (!objs) +- goto err_free_entry; ++ goto err_put_id; + virtio_gpu_array_add_obj(objs, &bo->base.base); + + ret = virtio_gpu_array_lock_resv(objs); + if (ret != 0) + goto err_put_objs; ++ } else { ++ ret = dma_resv_lock(bo->base.base.resv, NULL); ++ if (ret) ++ goto err_put_id; + } + + if (params->blob) { +- if (params->blob_mem == VIRTGPU_BLOB_MEM_GUEST) +- bo->guest_blob = true; ++ ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); ++ if (ret) ++ goto err_unlock_objs; ++ } else { ++ bo->detached = true; ++ } + ++ if (params->blob) + virtio_gpu_cmd_resource_create_blob(vgdev, bo, params, + ents, nents); +- } else if (params->virgl) { ++ else if (params->virgl) + virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, + objs, fence); +- virtio_gpu_object_attach(vgdev, bo, ents, nents); +- } else { ++ else + virtio_gpu_cmd_create_resource(vgdev, bo, params, + objs, fence); +- virtio_gpu_object_attach(vgdev, bo, ents, nents); +- } ++ ++ if (!fence) ++ dma_resv_unlock(bo->base.base.resv); + + *bo_ptr = bo; + return 0; + ++err_unlock_objs: ++ if (fence) ++ virtio_gpu_array_unlock_resv(objs); ++ else ++ dma_resv_unlock(bo->base.base.resv); + err_put_objs: + virtio_gpu_array_put_free(objs); +-err_free_entry: +- kvfree(ents); + err_put_id: + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); + err_put_pages: +diff --git a/drivers/gpu/drm/virtio/virtgpu_submit.c b/drivers/gpu/drm/virtio/virtgpu_submit.c +index 5c514946bbad..6e4ef2593e8f 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_submit.c ++++ b/drivers/gpu/drm/virtio/virtgpu_submit.c +@@ -464,8 +464,19 @@ static void virtio_gpu_install_out_fence_fd(struct virtio_gpu_submit *submit) + + static int virtio_gpu_lock_buflist(struct virtio_gpu_submit *submit) + { +- if (submit->buflist) +- return virtio_gpu_array_lock_resv(submit->buflist); ++ int err; ++ ++ if (submit->buflist) { ++ err = virtio_gpu_array_lock_resv(submit->buflist); ++ if (err) ++ return err; ++ ++ err = virtio_gpu_array_prepare(submit->vgdev, submit->buflist); ++ if (err) { ++ virtio_gpu_array_unlock_resv(submit->buflist); ++ return err; ++ } ++ } + + return 0; + } +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 29/30] drm/virtio: Support shmem shrinking + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (27 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 2024-01-05 18:46 ` [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker Dmitry Osipenko + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Support generic drm-shmem memory shrinker and add new madvise IOCTL to +the VirtIO-GPU driver. BO cache manager of Mesa driver will mark BOs as +"don't need" using the new IOCTL to let shrinker purge the marked BOs on +OOM, the shrinker will also evict unpurgeable shmem BOs from memory if +guest supports SWAP file or partition. + +Link: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15278 +Acked-by: Gerd Hoffmann +Signed-off-by: Daniel Almeida +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/virtio/virtgpu_drv.h | 13 +++++- + drivers/gpu/drm/virtio/virtgpu_gem.c | 48 +++++++++++++++++-- + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 25 ++++++++++ + drivers/gpu/drm/virtio/virtgpu_kms.c | 8 ++++ + drivers/gpu/drm/virtio/virtgpu_object.c | 61 +++++++++++++++++++++++++ + drivers/gpu/drm/virtio/virtgpu_vq.c | 40 ++++++++++++++++ + include/uapi/drm/virtgpu_drm.h | 14 ++++++ + 7 files changed, 204 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index 1837dc7ea9fb..37188c00e161 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -283,7 +283,7 @@ struct virtio_gpu_fpriv { + }; + + /* virtgpu_ioctl.c */ +-#define DRM_VIRTIO_NUM_IOCTLS 12 ++#define DRM_VIRTIO_NUM_IOCTLS 13 + extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; + void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file); + +@@ -321,6 +321,8 @@ void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + void virtio_gpu_array_put_free_work(struct work_struct *work); + int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs); ++int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo); ++int virtio_gpu_gem_madvise(struct virtio_gpu_object *obj, int madv); + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo); + void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo); + +@@ -334,6 +336,8 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, + struct virtio_gpu_fence *fence); + void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo); ++int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *bo); + void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, + uint64_t offset, + uint32_t width, uint32_t height, +@@ -354,6 +358,9 @@ void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *obj, + struct virtio_gpu_mem_entry *ents, + unsigned int nents); ++void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *obj, ++ struct virtio_gpu_fence *fence); + void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, + struct virtio_gpu_output *output); + int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev); +@@ -497,4 +504,8 @@ void virtio_gpu_vram_unmap_dma_buf(struct device *dev, + int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); + ++/* virtgpu_gem_shrinker.c */ ++int virtio_gpu_gem_shrinker_init(struct virtio_gpu_device *vgdev); ++void virtio_gpu_gem_shrinker_fini(struct virtio_gpu_device *vgdev); ++ + #endif +diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c +index 97e67064c97e..68d27ae582ba 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_gem.c ++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c +@@ -147,10 +147,20 @@ void virtio_gpu_gem_object_close(struct drm_gem_object *obj, + struct virtio_gpu_device *vgdev = obj->dev->dev_private; + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; + struct virtio_gpu_object_array *objs; ++ struct virtio_gpu_object *bo; + + if (!vgdev->has_virgl_3d) + return; + ++ bo = gem_to_virtio_gpu_obj(obj); ++ ++ /* ++ * Purged BO was already detached and released, the resource ID ++ * is invalid by now. ++ */ ++ if (!virtio_gpu_gem_madvise(bo, VIRTGPU_MADV_WILLNEED)) ++ return; ++ + objs = virtio_gpu_array_alloc(1); + if (!objs) + return; +@@ -305,16 +315,46 @@ int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev, + for (i = 0; i < objs->nents; i++) { + bo = gem_to_virtio_gpu_obj(objs->objs[i]); + +- if (virtio_gpu_is_shmem(bo) && bo->detached) { +- ret = virtio_gpu_reattach_shmem_object_locked(bo); +- if (ret) +- break; ++ if (virtio_gpu_is_shmem(bo)) { ++ if (bo->base.madv) ++ return -EINVAL; ++ ++ if (bo->detached) { ++ ret = virtio_gpu_reattach_shmem_object_locked(bo); ++ if (ret) ++ break; ++ } + } + } + + return ret; + } + ++int virtio_gpu_gem_madvise(struct virtio_gpu_object *bo, int madv) ++{ ++ if (virtio_gpu_is_shmem(bo)) ++ return drm_gem_shmem_object_madvise(&bo->base.base, madv); ++ ++ return 1; ++} ++ ++int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; ++ int err; ++ ++ if (bo->created) { ++ err = virtio_gpu_cmd_release_resource(vgdev, bo); ++ if (err) ++ return err; ++ ++ virtio_gpu_notify(vgdev); ++ bo->created = false; ++ } ++ ++ return 0; ++} ++ + int virtio_gpu_gem_pin(struct virtio_gpu_object *bo) + { + int err; +diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +index c7da22006149..a42799146090 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c ++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +@@ -701,6 +701,28 @@ static int virtio_gpu_context_init_ioctl(struct drm_device *dev, + return ret; + } + ++static int virtio_gpu_madvise_ioctl(struct drm_device *dev, ++ void *data, ++ struct drm_file *file) ++{ ++ struct drm_virtgpu_madvise *args = data; ++ struct virtio_gpu_object *bo; ++ struct drm_gem_object *obj; ++ ++ if (args->madv > VIRTGPU_MADV_DONTNEED) ++ return -EOPNOTSUPP; ++ ++ obj = drm_gem_object_lookup(file, args->bo_handle); ++ if (!obj) ++ return -ENOENT; ++ ++ bo = gem_to_virtio_gpu_obj(obj); ++ args->retained = virtio_gpu_gem_madvise(bo, args->madv); ++ drm_gem_object_put(obj); ++ ++ return 0; ++} ++ + struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { + DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl, + DRM_RENDER_ALLOW), +@@ -740,4 +762,7 @@ struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { + + DRM_IOCTL_DEF_DRV(VIRTGPU_CONTEXT_INIT, virtio_gpu_context_init_ioctl, + DRM_RENDER_ALLOW), ++ ++ DRM_IOCTL_DEF_DRV(VIRTGPU_MADVISE, virtio_gpu_madvise_ioctl, ++ DRM_RENDER_ALLOW), + }; +diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c +index 5a3b5aaed1f3..43e237082cec 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_kms.c ++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c +@@ -245,6 +245,12 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) + goto err_scanouts; + } + ++ ret = drmm_gem_shmem_init(dev); ++ if (ret) { ++ DRM_ERROR("shmem init failed\n"); ++ goto err_modeset; ++ } ++ + virtio_device_ready(vgdev->vdev); + + if (num_capsets) +@@ -259,6 +265,8 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) + } + return 0; + ++err_modeset: ++ virtio_gpu_modeset_fini(vgdev); + err_scanouts: + virtio_gpu_free_vbufs(vgdev); + err_vbufs: +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index de347aa3b9a8..86888c1ae5d4 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -98,6 +98,60 @@ static void virtio_gpu_free_object(struct drm_gem_object *obj) + virtio_gpu_cleanup_object(bo); + } + ++static int virtio_gpu_detach_object_fenced(struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; ++ struct virtio_gpu_fence *fence; ++ ++ if (bo->detached) ++ return 0; ++ ++ fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0); ++ if (!fence) ++ return -ENOMEM; ++ ++ virtio_gpu_object_detach(vgdev, bo, fence); ++ virtio_gpu_notify(vgdev); ++ ++ dma_fence_wait(&fence->f, false); ++ dma_fence_put(&fence->f); ++ ++ bo->detached = true; ++ ++ return 0; ++} ++ ++static int virtio_gpu_shmem_evict(struct drm_gem_object *obj) ++{ ++ struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); ++ int err; ++ ++ /* blob is not movable, it's impossible to detach it from host */ ++ if (bo->blob_mem) ++ return -EBUSY; ++ ++ /* ++ * At first tell host to stop using guest's memory to ensure that ++ * host won't touch the released guest's memory once it's gone. ++ */ ++ err = virtio_gpu_detach_object_fenced(bo); ++ if (err) ++ return err; ++ ++ if (drm_gem_shmem_is_purgeable(&bo->base)) { ++ err = virtio_gpu_gem_host_mem_release(bo); ++ if (err) ++ return err; ++ ++ drm_gem_shmem_purge_locked(&bo->base); ++ } else { ++ bo->base.pages_mark_dirty_on_put = 1; ++ drm_gem_shmem_evict_locked(&bo->base); ++ } ++ ++ return 0; ++} ++ + static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = { + .free = virtio_gpu_free_object, + .open = virtio_gpu_gem_object_open, +@@ -111,6 +165,7 @@ static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = { + .vunmap = drm_gem_shmem_object_vunmap, + .mmap = drm_gem_shmem_object_mmap, + .vm_ops = &drm_gem_shmem_vm_ops, ++ .evict = virtio_gpu_shmem_evict, + }; + + bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo) +@@ -187,6 +242,10 @@ int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo) + if (!bo->detached) + return 0; + ++ err = drm_gem_shmem_swapin_locked(&bo->base); ++ if (err) ++ return err; ++ + err = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); + if (err) + return err; +@@ -240,6 +299,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + goto err_put_pages; + + bo->dumb = params->dumb; ++ bo->blob_mem = params->blob_mem; ++ bo->blob_flags = params->blob_flags; + + if (bo->blob_mem == VIRTGPU_BLOB_MEM_GUEST) + bo->guest_blob = true; +diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c +index b1a00c0c25a7..14ab470f413a 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_vq.c ++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c +@@ -545,6 +545,21 @@ void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, + virtio_gpu_cleanup_object(bo); + } + ++int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *bo) ++{ ++ struct virtio_gpu_resource_unref *cmd_p; ++ struct virtio_gpu_vbuffer *vbuf; ++ ++ cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); ++ memset(cmd_p, 0, sizeof(*cmd_p)); ++ ++ cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_UNREF); ++ cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); ++ ++ return virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); ++} ++ + void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, uint32_t resource_id, + uint32_t width, uint32_t height, +@@ -645,6 +660,23 @@ virtio_gpu_cmd_resource_attach_backing(struct virtio_gpu_device *vgdev, + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + } + ++static void ++virtio_gpu_cmd_resource_detach_backing(struct virtio_gpu_device *vgdev, ++ u32 resource_id, ++ struct virtio_gpu_fence *fence) ++{ ++ struct virtio_gpu_resource_attach_backing *cmd_p; ++ struct virtio_gpu_vbuffer *vbuf; ++ ++ cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); ++ memset(cmd_p, 0, sizeof(*cmd_p)); ++ ++ cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING); ++ cmd_p->resource_id = cpu_to_le32(resource_id); ++ ++ virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); ++} ++ + static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, + struct virtio_gpu_vbuffer *vbuf) + { +@@ -1107,6 +1139,14 @@ void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, + ents, nents, NULL); + } + ++void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev, ++ struct virtio_gpu_object *obj, ++ struct virtio_gpu_fence *fence) ++{ ++ virtio_gpu_cmd_resource_detach_backing(vgdev, obj->hw_res_handle, ++ fence); ++} ++ + void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, + struct virtio_gpu_output *output) + { +diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h +index c2ce71987e9b..78255060bc9a 100644 +--- a/include/uapi/drm/virtgpu_drm.h ++++ b/include/uapi/drm/virtgpu_drm.h +@@ -48,6 +48,7 @@ extern "C" { + #define DRM_VIRTGPU_GET_CAPS 0x09 + #define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a + #define DRM_VIRTGPU_CONTEXT_INIT 0x0b ++#define DRM_VIRTGPU_MADVISE 0x0c + + #define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01 + #define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02 +@@ -213,6 +214,15 @@ struct drm_virtgpu_context_init { + __u64 ctx_set_params; + }; + ++#define VIRTGPU_MADV_WILLNEED 0 ++#define VIRTGPU_MADV_DONTNEED 1 ++struct drm_virtgpu_madvise { ++ __u32 bo_handle; ++ __u32 retained; /* out, non-zero if BO can be used */ ++ __u32 madv; ++ __u32 pad; ++}; ++ + /* + * Event code that's given when VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK is in + * effect. The event size is sizeof(drm_event), since there is no additional +@@ -263,6 +273,10 @@ struct drm_virtgpu_context_init { + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_CONTEXT_INIT, \ + struct drm_virtgpu_context_init) + ++#define DRM_IOCTL_VIRTGPU_MADVISE \ ++ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MADVISE, \ ++ struct drm_virtgpu_madvise) ++ + #if defined(__cplusplus) + } + #endif +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +* [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker + 2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko + ` (28 preceding siblings ...) + 2024-01-05 18:46 ` [PATCH v19 29/30] drm/virtio: Support shmem shrinking Dmitry Osipenko +@ 2024-01-05 18:46 ` Dmitry Osipenko + 29 siblings, 0 replies; 31+ messages in thread +From: Dmitry Osipenko @ 2024-01-05 18:46 UTC (permalink / raw) + To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu, + Daniel Vetter, Maarten Lankhorst, Maxime Ripard, + Thomas Zimmermann, Christian König, Qiang Yu, Steven Price, + Boris Brezillon, Emma Anholt, Melissa Wen + Cc: dri-devel, linux-kernel, kernel, virtualization + +Replace Panfrost's custom memory shrinker with a common drm-shmem +memory shrinker. + +Co-developed-by: Boris Brezillon +Signed-off-by: Boris Brezillon +Signed-off-by: Dmitry Osipenko +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 4 +- + drivers/gpu/drm/panfrost/Makefile | 1 - + drivers/gpu/drm/panfrost/panfrost_device.h | 4 - + drivers/gpu/drm/panfrost/panfrost_drv.c | 29 ++-- + drivers/gpu/drm/panfrost/panfrost_gem.c | 60 ++++---- + drivers/gpu/drm/panfrost/panfrost_gem.h | 9 -- + .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 140 ------------------ + drivers/gpu/drm/panfrost/panfrost_job.c | 18 ++- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 24 ++- + include/drm/drm_gem_shmem_helper.h | 7 - + 10 files changed, 83 insertions(+), 213 deletions(-) + delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c + +diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c +index 7d2fe12bd793..56e88378079b 100644 +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -89,8 +89,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private) + if (ret) + goto err_release; + +- INIT_LIST_HEAD(&shmem->madv_list); +- + if (!private) { + /* + * Our buffers are kept pinned, so allocating them +@@ -619,6 +617,8 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) + { + struct drm_gem_object *obj = &shmem->base; + ++ drm_WARN_ON_ONCE(obj->dev, !drm_gem_shmem_is_purgeable(shmem)); ++ + drm_gem_shmem_shrinker_put_pages_locked(shmem); + drm_gem_free_mmap_offset(obj); + +diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile +index 2c01c1e7523e..f2cb1ab0a32d 100644 +--- a/drivers/gpu/drm/panfrost/Makefile ++++ b/drivers/gpu/drm/panfrost/Makefile +@@ -5,7 +5,6 @@ panfrost-y := \ + panfrost_device.o \ + panfrost_devfreq.o \ + panfrost_gem.o \ +- panfrost_gem_shrinker.o \ + panfrost_gpu.o \ + panfrost_job.o \ + panfrost_mmu.o \ +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index 62f7e3527385..cea6df9cd650 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -140,10 +140,6 @@ struct panfrost_device { + atomic_t pending; + } reset; + +- struct mutex shrinker_lock; +- struct list_head shrinker_list; +- struct shrinker *shrinker; +- + struct panfrost_devfreq pfdevfreq; + + struct { +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index a15d62f19afb..5c730d15a24d 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -171,7 +171,6 @@ panfrost_lookup_bos(struct drm_device *dev, + break; + } + +- atomic_inc(&bo->gpu_usecount); + job->mappings[i] = mapping; + } + +@@ -397,7 +396,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + { + struct panfrost_file_priv *priv = file_priv->driver_priv; + struct drm_panfrost_madvise *args = data; +- struct panfrost_device *pfdev = dev->dev_private; + struct drm_gem_object *gem_obj; + struct panfrost_gem_object *bo; + int ret = 0; +@@ -410,11 +408,15 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + + bo = to_panfrost_bo(gem_obj); + ++ if (bo->is_heap) { ++ args->retained = 1; ++ goto out_put_object; ++ } ++ + ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL); + if (ret) + goto out_put_object; + +- mutex_lock(&pfdev->shrinker_lock); + mutex_lock(&bo->mappings.lock); + if (args->madv == PANFROST_MADV_DONTNEED) { + struct panfrost_gem_mapping *first; +@@ -440,17 +442,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, + + args->retained = drm_gem_shmem_madvise_locked(&bo->base, args->madv); + +- if (args->retained) { +- if (args->madv == PANFROST_MADV_DONTNEED) +- list_move_tail(&bo->base.madv_list, +- &pfdev->shrinker_list); +- else if (args->madv == PANFROST_MADV_WILLNEED) +- list_del_init(&bo->base.madv_list); +- } +- + out_unlock_mappings: + mutex_unlock(&bo->mappings.lock); +- mutex_unlock(&pfdev->shrinker_lock); + dma_resv_unlock(bo->base.base.resv); + out_put_object: + drm_gem_object_put(gem_obj); +@@ -635,9 +628,6 @@ static int panfrost_probe(struct platform_device *pdev) + ddev->dev_private = pfdev; + pfdev->ddev = ddev; + +- mutex_init(&pfdev->shrinker_lock); +- INIT_LIST_HEAD(&pfdev->shrinker_list); +- + err = panfrost_device_init(pfdev); + if (err) { + if (err != -EPROBE_DEFER) +@@ -659,13 +649,13 @@ static int panfrost_probe(struct platform_device *pdev) + if (err < 0) + goto err_out1; + +- err = panfrost_gem_shrinker_init(ddev); +- if (err) +- goto err_out2; ++ err = drmm_gem_shmem_init(ddev); ++ if (err < 0) ++ goto err_unregister_dev; + + return 0; + +-err_out2: ++err_unregister_dev: + drm_dev_unregister(ddev); + err_out1: + pm_runtime_disable(pfdev->dev); +@@ -682,7 +672,6 @@ static void panfrost_remove(struct platform_device *pdev) + struct drm_device *ddev = pfdev->ddev; + + drm_dev_unregister(ddev); +- panfrost_gem_shrinker_cleanup(ddev); + + pm_runtime_get_sync(pfdev->dev); + pm_runtime_disable(pfdev->dev); +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index 8c26b7e41b95..05eb5a89c4ed 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -17,17 +17,6 @@ + static void panfrost_gem_free_object(struct drm_gem_object *obj) + { + struct panfrost_gem_object *bo = to_panfrost_bo(obj); +- struct panfrost_device *pfdev = obj->dev->dev_private; +- +- /* +- * Make sure the BO is no longer inserted in the shrinker list before +- * taking care of the destruction itself. If we don't do that we have a +- * race condition between this function and what's done in +- * panfrost_gem_shrinker_scan(). +- */ +- mutex_lock(&pfdev->shrinker_lock); +- list_del_init(&bo->base.madv_list); +- mutex_unlock(&pfdev->shrinker_lock); + + /* + * If we still have mappings attached to the BO, there's a problem in +@@ -57,26 +46,23 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, + return mapping; + } + +-static void +-panfrost_gem_teardown_mapping(struct panfrost_gem_mapping *mapping) ++static void panfrost_gem_mapping_release(struct kref *kref) + { ++ struct panfrost_gem_mapping *mapping = ++ container_of(kref, struct panfrost_gem_mapping, refcount); ++ struct panfrost_gem_object *bo = mapping->obj; ++ struct panfrost_device *pfdev = bo->base.base.dev->dev_private; ++ ++ /* Shrinker may purge the mapping at the same time. */ ++ dma_resv_lock(mapping->obj->base.base.resv, NULL); + if (mapping->active) + panfrost_mmu_unmap(mapping); ++ dma_resv_unlock(mapping->obj->base.base.resv); + + spin_lock(&mapping->mmu->mm_lock); + if (drm_mm_node_allocated(&mapping->mmnode)) + drm_mm_remove_node(&mapping->mmnode); + spin_unlock(&mapping->mmu->mm_lock); +-} +- +-static void panfrost_gem_mapping_release(struct kref *kref) +-{ +- struct panfrost_gem_mapping *mapping = +- container_of(kref, struct panfrost_gem_mapping, refcount); +- struct panfrost_gem_object *bo = mapping->obj; +- struct panfrost_device *pfdev = bo->base.base.dev->dev_private; +- +- panfrost_gem_teardown_mapping(mapping); + + /* On heap BOs, release the sgts created in the fault handler path. */ + if (bo->sgts) { +@@ -117,12 +103,14 @@ void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping) + kref_put(&mapping->refcount, panfrost_gem_mapping_release); + } + +-void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo) ++void panfrost_gem_evict_mappings_locked(struct panfrost_gem_object *bo) + { + struct panfrost_gem_mapping *mapping; + +- list_for_each_entry(mapping, &bo->mappings.list, node) +- panfrost_gem_teardown_mapping(mapping); ++ list_for_each_entry(mapping, &bo->mappings.list, node) { ++ if (mapping->active) ++ panfrost_mmu_unmap(mapping); ++ } + } + + int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) +@@ -251,6 +239,25 @@ static size_t panfrost_gem_rss(struct drm_gem_object *obj) + return 0; + } + ++static int panfrost_shmem_evict(struct drm_gem_object *obj) ++{ ++ struct panfrost_gem_object *bo = to_panfrost_bo(obj); ++ ++ if (!drm_gem_shmem_is_purgeable(&bo->base)) ++ return -EBUSY; ++ ++ if (!mutex_trylock(&bo->mappings.lock)) ++ return -EBUSY; ++ ++ panfrost_gem_evict_mappings_locked(bo); ++ ++ drm_gem_shmem_purge_locked(&bo->base); ++ ++ mutex_unlock(&bo->mappings.lock); ++ ++ return 0; ++} ++ + static const struct drm_gem_object_funcs panfrost_gem_funcs = { + .free = panfrost_gem_free_object, + .open = panfrost_gem_open, +@@ -265,6 +272,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = { + .status = panfrost_gem_status, + .rss = panfrost_gem_rss, + .vm_ops = &drm_gem_shmem_vm_ops, ++ .evict = panfrost_shmem_evict, + }; + + /** +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h +index 7516b7ecf7fe..8ddc2d310d29 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.h ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.h +@@ -30,12 +30,6 @@ struct panfrost_gem_object { + struct mutex lock; + } mappings; + +- /* +- * Count the number of jobs referencing this BO so we don't let the +- * shrinker reclaim this object prematurely. +- */ +- atomic_t gpu_usecount; +- + /* + * Object chunk size currently mapped onto physical memory + */ +@@ -86,7 +80,4 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, + void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); + void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); + +-int panfrost_gem_shrinker_init(struct drm_device *dev); +-void panfrost_gem_shrinker_cleanup(struct drm_device *dev); +- + #endif /* __PANFROST_GEM_H__ */ +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +deleted file mode 100644 +index 7b4deba803ed..000000000000 +--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c ++++ /dev/null +@@ -1,140 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* Copyright (C) 2019 Arm Ltd. +- * +- * Based on msm_gem_freedreno.c: +- * Copyright (C) 2016 Red Hat +- * Author: Rob Clark +- */ +- +-#include +- +-#include +-#include +- +-#include "panfrost_device.h" +-#include "panfrost_gem.h" +-#include "panfrost_mmu.h" +- +-static bool panfrost_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem) +-{ +- return (shmem->madv > 0) && +- !refcount_read(&shmem->pages_pin_count) && shmem->sgt && +- !shmem->base.dma_buf && !shmem->base.import_attach; +-} +- +-static unsigned long +-panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) +-{ +- struct panfrost_device *pfdev = shrinker->private_data; +- struct drm_gem_shmem_object *shmem; +- unsigned long count = 0; +- +- if (!mutex_trylock(&pfdev->shrinker_lock)) +- return 0; +- +- list_for_each_entry(shmem, &pfdev->shrinker_list, madv_list) { +- if (panfrost_gem_shmem_is_purgeable(shmem)) +- count += shmem->base.size >> PAGE_SHIFT; +- } +- +- mutex_unlock(&pfdev->shrinker_lock); +- +- return count; +-} +- +-static bool panfrost_gem_purge(struct drm_gem_object *obj) +-{ +- struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); +- struct panfrost_gem_object *bo = to_panfrost_bo(obj); +- bool ret = false; +- +- if (atomic_read(&bo->gpu_usecount)) +- return false; +- +- if (!mutex_trylock(&bo->mappings.lock)) +- return false; +- +- if (!dma_resv_trylock(shmem->base.resv)) +- goto unlock_mappings; +- +- /* BO might have become unpurgeable if the last pages_use_count ref +- * was dropped, but the BO hasn't been destroyed yet. +- */ +- if (!panfrost_gem_shmem_is_purgeable(shmem)) +- goto unlock_mappings; +- +- panfrost_gem_teardown_mappings_locked(bo); +- drm_gem_shmem_purge_locked(&bo->base); +- ret = true; +- +- dma_resv_unlock(shmem->base.resv); +- +-unlock_mappings: +- mutex_unlock(&bo->mappings.lock); +- return ret; +-} +- +-static unsigned long +-panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) +-{ +- struct panfrost_device *pfdev = shrinker->private_data; +- struct drm_gem_shmem_object *shmem, *tmp; +- unsigned long freed = 0; +- +- if (!mutex_trylock(&pfdev->shrinker_lock)) +- return SHRINK_STOP; +- +- list_for_each_entry_safe(shmem, tmp, &pfdev->shrinker_list, madv_list) { +- if (freed >= sc->nr_to_scan) +- break; +- if (panfrost_gem_shmem_is_purgeable(shmem) && +- panfrost_gem_purge(&shmem->base)) { +- freed += shmem->base.size >> PAGE_SHIFT; +- list_del_init(&shmem->madv_list); +- } +- } +- +- mutex_unlock(&pfdev->shrinker_lock); +- +- if (freed > 0) +- pr_info_ratelimited("Purging %lu bytes\n", freed << PAGE_SHIFT); +- +- return freed; +-} +- +-/** +- * panfrost_gem_shrinker_init - Initialize panfrost shrinker +- * @dev: DRM device +- * +- * This function registers and sets up the panfrost shrinker. +- */ +-int panfrost_gem_shrinker_init(struct drm_device *dev) +-{ +- struct panfrost_device *pfdev = dev->dev_private; +- +- pfdev->shrinker = shrinker_alloc(0, "drm-panfrost"); +- if (!pfdev->shrinker) +- return -ENOMEM; +- +- pfdev->shrinker->count_objects = panfrost_gem_shrinker_count; +- pfdev->shrinker->scan_objects = panfrost_gem_shrinker_scan; +- pfdev->shrinker->private_data = pfdev; +- +- shrinker_register(pfdev->shrinker); +- +- return 0; +-} +- +-/** +- * panfrost_gem_shrinker_cleanup - Clean up panfrost shrinker +- * @dev: DRM device +- * +- * This function unregisters the panfrost shrinker. +- */ +-void panfrost_gem_shrinker_cleanup(struct drm_device *dev) +-{ +- struct panfrost_device *pfdev = dev->dev_private; +- +- if (pfdev->shrinker) +- shrinker_free(pfdev->shrinker); +-} +diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c +index 0c2dbf6ef2a5..9e26cb013191 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_job.c ++++ b/drivers/gpu/drm/panfrost/panfrost_job.c +@@ -289,6 +289,19 @@ static void panfrost_attach_object_fences(struct drm_gem_object **bos, + dma_resv_add_fence(bos[i]->resv, fence, DMA_RESV_USAGE_WRITE); + } + ++static int panfrost_objects_prepare(struct drm_gem_object **bos, int bo_count) ++{ ++ struct panfrost_gem_object *bo; ++ int ret = 0; ++ ++ while (!ret && bo_count--) { ++ bo = to_panfrost_bo(bos[bo_count]); ++ ret = bo->base.madv != PANFROST_MADV_WILLNEED ? -EINVAL : 0; ++ } ++ ++ return ret; ++} ++ + int panfrost_job_push(struct panfrost_job *job) + { + struct panfrost_device *pfdev = job->pfdev; +@@ -300,6 +313,10 @@ int panfrost_job_push(struct panfrost_job *job) + if (ret) + return ret; + ++ ret = panfrost_objects_prepare(job->bos, job->bo_count); ++ if (ret) ++ goto unlock; ++ + mutex_lock(&pfdev->sched_lock); + drm_sched_job_arm(&job->base); + +@@ -341,7 +358,6 @@ static void panfrost_job_cleanup(struct kref *ref) + if (!job->mappings[i]) + break; + +- atomic_dec(&job->mappings[i]->obj->gpu_usecount); + panfrost_gem_mapping_put(job->mappings[i]); + } + kvfree(job->mappings); +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 4a0b4bf03f1a..22e18f7986e7 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -328,6 +328,7 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) + struct panfrost_device *pfdev = to_panfrost_device(obj->dev); + struct sg_table *sgt; + int prot = IOMMU_READ | IOMMU_WRITE; ++ int ret = 0; + + if (WARN_ON(mapping->active)) + return 0; +@@ -335,15 +336,32 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) + if (bo->noexec) + prot |= IOMMU_NOEXEC; + ++ if (!obj->import_attach) { ++ /* ++ * Don't allow shrinker to move pages while pages are mapped. ++ * It's fine to move pages afterwards because shrinker will ++ * take care of unmapping pages during eviction. ++ */ ++ ret = drm_gem_shmem_pin(shmem); ++ if (ret) ++ return ret; ++ } ++ + sgt = drm_gem_shmem_get_pages_sgt(shmem); +- if (WARN_ON(IS_ERR(sgt))) +- return PTR_ERR(sgt); ++ if (WARN_ON(IS_ERR(sgt))) { ++ ret = PTR_ERR(sgt); ++ goto unpin; ++ } + + mmu_map_sg(pfdev, mapping->mmu, mapping->mmnode.start << PAGE_SHIFT, + prot, sgt); + mapping->active = true; + +- return 0; ++unpin: ++ if (!obj->import_attach) ++ drm_gem_shmem_unpin(shmem); ++ ++ return ret; + } + + void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping) +diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h +index 167f00f089de..9c6bb00260fc 100644 +--- a/include/drm/drm_gem_shmem_helper.h ++++ b/include/drm/drm_gem_shmem_helper.h +@@ -61,13 +61,6 @@ struct drm_gem_shmem_object { + */ + int madv; + +- /** +- * @madv_list: List entry for madvise tracking +- * +- * Typically used by drivers to track purgeable objects +- */ +- struct list_head madv_list; +- + /** + * @sgt: Scatter/gather table for imported PRIME buffers + */ +-- +2.43.0 + + +^ permalink raw reply related [flat|nested] 31+ messages in thread +end of thread, other threads:[~2024-01-05 18:47 UTC | newest] + +Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed) +-- links below jump to the message on this page -- +2024-01-05 18:45 [PATCH v19 00/30] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 01/30] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 02/30] drm/gem: Add _locked postfix to functions that have unlocked counterpart Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 03/30] drm/gem: Document locking rule of vmap and evict callbacks Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 04/30] drm/shmem-helper: Make all exported symbols GPL Dmitry Osipenko +2024-01-05 18:45 ` [PATCH v19 05/30] drm/shmem-helper: Refactor locked/unlocked functions Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 06/30] drm/shmem-helper: Remove obsoleted is_iomem test Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 07/30] drm/shmem-helper: Add and use pages_pin_count Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 08/30] drm/shmem-helper: Use refcount_t for pages_use_count Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 09/30] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 10/30] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 11/30] drm/shmem-helper: Use refcount_t for vmap_use_count Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 12/30] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 13/30] drm/shmem-helper: Make drm_gem_shmem_get_pages() public Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 14/30] drm/shmem-helper: Add drm_gem_shmem_put_pages() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 15/30] drm/shmem-helper: Avoid lockdep warning when pages are released Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 16/30] drm/lima: Explicitly get and put drm-shmem pages Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 17/30] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 18/30] drm/panfrost: Explicitly get and put drm-shmem pages Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 19/30] drm/virtio: " Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 20/30] drm/v3d: " Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 21/30] drm/shmem-helper: Change sgt allocation policy Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 22/30] drm/shmem-helper: Add common memory shrinker Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 23/30] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 24/30] drm/shmem-helper: Optimize unlocked get_pages_sgt() Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 25/30] drm/shmem-helper: Don't free refcounted GEM Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 26/30] drm/shmem-helper: Turn warnings about imported GEM into errors Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 27/30] drm/virtio: Pin display framebuffer BO Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 28/30] drm/virtio: Attach shmem BOs dynamically Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 29/30] drm/virtio: Support shmem shrinking Dmitry Osipenko +2024-01-05 18:46 ` [PATCH v19 30/30] drm/panfrost: Switch to generic memory shrinker Dmitry Osipenko +This is a public inbox, see mirroring instructions +for how to clone and mirror all data and code used for this inbox; +as well as URLs for NNTP newsgroup(s). diff --git a/projects/Rockchip/packages/linux/patches/RK3566/0001-drm-panel-Add-helper-for-reading-DT-rotation.patch b/projects/Rockchip/packages/linux/patches/RK3566/0001-drm-panel-Add-helper-for-reading-DT-rotation.patch new file mode 100644 index 0000000000..b0cc4f5e31 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RK3566/0001-drm-panel-Add-helper-for-reading-DT-rotation.patch @@ -0,0 +1,103 @@ +From c74b76bb8a4da44a9f8cf06f4aba9f3334e1a148 Mon Sep 17 00:00:00 2001 +From: Derek Basehore +Date: Tue, 9 Jul 2019 19:16:56 -0700 +Subject: [PATCH 1/4] drm/panel: Add helper for reading DT rotation + +This adds a helper function for reading the rotation (panel +orientation) from the device tree. + +Signed-off-by: Derek Basehore +--- + drivers/gpu/drm/drm_panel.c | 43 +++++++++++++++++++++++++++++++++++++ + include/drm/drm_panel.h | 9 ++++++++ + 2 files changed, 52 insertions(+) + +diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c +index d37b83f40..b2d8fa2c3 100644 +--- a/drivers/gpu/drm/drm_panel.c ++++ b/drivers/gpu/drm/drm_panel.c +@@ -168,6 +168,49 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np) + return ERR_PTR(-EPROBE_DEFER); + } + EXPORT_SYMBOL(of_drm_find_panel); ++ ++/** ++ * of_drm_get_panel_orientation - look up the orientation of the panel through ++ * the "rotation" binding from a device tree node ++ * @np: device tree node of the panel ++ * @orientation: orientation enum to be filled in ++ * ++ * Looks up the rotation of a panel in the device tree. The orientation of the ++ * panel is expressed as a property name "rotation" in the device tree. The ++ * rotation in the device tree is counter clockwise. ++ * ++ * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the ++ * rotation property doesn't exist. -EERROR otherwise. ++ */ ++int of_drm_get_panel_orientation(const struct device_node *np, ++ enum drm_panel_orientation *orientation) ++{ ++ int rotation, ret; ++ ++ ret = of_property_read_u32(np, "rotation", &rotation); ++ if (ret == -EINVAL) { ++ /* Don't return an error if there's no rotation property. */ ++ *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; ++ return 0; ++ } ++ ++ if (ret < 0) ++ return ret; ++ ++ if (rotation == 0) ++ *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; ++ else if (rotation == 90) ++ *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP; ++ else if (rotation == 180) ++ *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; ++ else if (rotation == 270) ++ *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; ++ else ++ return -EINVAL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(of_drm_get_panel_orientation); + #endif + + int drm_panel_notifier_register(struct drm_panel *panel, +diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h +index 6aab8fefc..c58c4c19f 100644 +--- a/include/drm/drm_panel.h ++++ b/include/drm/drm_panel.h +@@ -53,6 +53,8 @@ struct drm_device; + struct drm_panel; + struct display_timing; + ++enum drm_panel_orientation; ++ + /** + * @loader_protect: protect loader logo panel's power + * struct drm_panel_funcs - perform operations on a given panel +@@ -240,11 +242,18 @@ int drm_panel_notifier_call_chain(struct drm_panel *panel, + + #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL) + struct drm_panel *of_drm_find_panel(const struct device_node *np); ++int of_drm_get_panel_orientation(const struct device_node *np, ++ enum drm_panel_orientation *orientation); + #else + static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) + { + return ERR_PTR(-ENODEV); + } ++static inline int of_drm_get_panel_orientation(const struct device_node *np, ++ enum drm_panel_orientation *orientation) ++{ ++ return -ENODEV; ++} + #endif + + #endif +-- +2.34.1 + diff --git a/projects/Rockchip/packages/linux/patches/RK3566/0002-drm-connector-Split-out-orientation-quirk-detection-.patch b/projects/Rockchip/packages/linux/patches/RK3566/0002-drm-connector-Split-out-orientation-quirk-detection-.patch new file mode 100644 index 0000000000..23f41607b7 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RK3566/0002-drm-connector-Split-out-orientation-quirk-detection-.patch @@ -0,0 +1,171 @@ +From b76306d4adb2e169f8425fb417de565d555fcf22 Mon Sep 17 00:00:00 2001 +From: Derek Basehore +Date: Sun, 5 Jan 2020 16:51:19 +0100 +Subject: [PATCH 2/4] drm/connector: Split out orientation quirk detection (v2) + +Not every platform needs quirk detection for panel orientation, so +split the drm_connector_init_panel_orientation_property into two +functions. One for platforms without the need for quirks, and the +other for platforms that need quirks. + +Hans de Goede (changes in v2): + +Rename the function from drm_connector_init_panel_orientation_property +to drm_connector_set_panel_orientation[_with_quirk] and pass in the +panel-orientation to set. + +Beside the rename, also make the function set the passed in value +only once, if the value was set before (to a value other then +DRM_MODE_PANEL_ORIENTATION_UNKNOWN) make any further set calls a no-op. + +This change is preparation for allowing the user to override the +panel-orientation for any connector from the kernel commandline. +When the panel-orientation is overridden this way, then we must ignore +the panel-orientation detection done by the driver. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Derek Basehore +Signed-off-by: Hans de Goede +Acked-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20200105155120.96466-1-hdegoede@redhat.com +--- + drivers/gpu/drm/drm_connector.c | 74 ++++++++++++++++++++++++--------- + include/drm/drm_connector.h | 9 +++- + 2 files changed, 61 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c +index 8a2a1965e..77a2087bf 100644 +--- a/drivers/gpu/drm/drm_connector.c ++++ b/drivers/gpu/drm/drm_connector.c +@@ -996,7 +996,8 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { + * coordinates, so if userspace rotates the picture to adjust for + * the orientation it must also apply the same transformation to the + * touchscreen input coordinates. This property is initialized by calling +- * drm_connector_init_panel_orientation_property(). ++ * drm_connector_set_panel_orientation() or ++ * drm_connector_set_panel_orientation_with_quirk() + * + * scaling mode: + * This property defines how a non-native mode is upscaled to the native +@@ -1713,38 +1714,41 @@ void drm_connector_set_link_status_property(struct drm_connector *connector, + EXPORT_SYMBOL(drm_connector_set_link_status_property); + + /** +- * drm_connector_init_panel_orientation_property - +- * initialize the connecters panel_orientation property +- * @connector: connector for which to init the panel-orientation property. +- * @width: width in pixels of the panel, used for panel quirk detection +- * @height: height in pixels of the panel, used for panel quirk detection ++ * drm_connector_set_panel_orientation - sets the connecter's panel_orientation ++ * @connector: connector for which to set the panel-orientation property. ++ * @panel_orientation: drm_panel_orientation value to set ++ * ++ * This function sets the connector's panel_orientation and attaches ++ * a "panel orientation" property to the connector. + * +- * This function should only be called for built-in panels, after setting +- * connector->display_info.panel_orientation first (if known). ++ * Calling this function on a connector where the panel_orientation has ++ * already been set is a no-op (e.g. the orientation has been overridden with ++ * a kernel commandline option). + * +- * This function will check for platform specific (e.g. DMI based) quirks +- * overriding display_info.panel_orientation first, then if panel_orientation +- * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the +- * "panel orientation" property to the connector. ++ * It is allowed to call this function with a panel_orientation of ++ * DRM_MODE_PANEL_ORIENTATION_UNKNOWN, in which case it is a no-op. + * + * Returns: + * Zero on success, negative errno on failure. + */ +-int drm_connector_init_panel_orientation_property( +- struct drm_connector *connector, int width, int height) ++int drm_connector_set_panel_orientation( ++ struct drm_connector *connector, ++ enum drm_panel_orientation panel_orientation) + { + struct drm_device *dev = connector->dev; + struct drm_display_info *info = &connector->display_info; + struct drm_property *prop; +- int orientation_quirk; + +- orientation_quirk = drm_get_panel_orientation_quirk(width, height); +- if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) +- info->panel_orientation = orientation_quirk; ++ /* Already set? */ ++ if (info->panel_orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) ++ return 0; + +- if (info->panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN) ++ /* Don't attach the property if the orientation is unknown */ ++ if (panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN) + return 0; + ++ info->panel_orientation = panel_orientation; ++ + prop = dev->mode_config.panel_orientation_property; + if (!prop) { + prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, +@@ -1761,7 +1765,37 @@ int drm_connector_init_panel_orientation_property( + info->panel_orientation); + return 0; + } +-EXPORT_SYMBOL(drm_connector_init_panel_orientation_property); ++EXPORT_SYMBOL(drm_connector_set_panel_orientation); ++ ++/** ++ * drm_connector_set_panel_orientation_with_quirk - ++ * set the connecter's panel_orientation after checking for quirks ++ * @connector: connector for which to init the panel-orientation property. ++ * @panel_orientation: drm_panel_orientation value to set ++ * @width: width in pixels of the panel, used for panel quirk detection ++ * @height: height in pixels of the panel, used for panel quirk detection ++ * ++ * Like drm_connector_set_panel_orientation(), but with a check for platform ++ * specific (e.g. DMI based) quirks overriding the passed in panel_orientation. ++ * ++ * Returns: ++ * Zero on success, negative errno on failure. ++ */ ++int drm_connector_set_panel_orientation_with_quirk( ++ struct drm_connector *connector, ++ enum drm_panel_orientation panel_orientation, ++ int width, int height) ++{ ++ int orientation_quirk; ++ ++ orientation_quirk = drm_get_panel_orientation_quirk(width, height); ++ if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) ++ panel_orientation = orientation_quirk; ++ ++ return drm_connector_set_panel_orientation(connector, ++ panel_orientation); ++} ++EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk); + + int drm_connector_set_obj_prop(struct drm_mode_object *obj, + struct drm_property *property, +diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h +index 1d81bb31f..44b6c7f85 100644 +--- a/include/drm/drm_connector.h ++++ b/include/drm/drm_connector.h +@@ -1473,8 +1473,13 @@ int drm_connector_update_edid_property(struct drm_connector *connector, + const struct edid *edid); + void drm_connector_set_link_status_property(struct drm_connector *connector, + uint64_t link_status); +-int drm_connector_init_panel_orientation_property( +- struct drm_connector *connector, int width, int height); ++int drm_connector_set_panel_orientation( ++ struct drm_connector *connector, ++ enum drm_panel_orientation panel_orientation); ++int drm_connector_set_panel_orientation_with_quirk( ++ struct drm_connector *connector, ++ enum drm_panel_orientation panel_orientation, ++ int width, int height); + + /** + * struct drm_tile_group - Tile group metadata +-- +2.34.1 + diff --git a/projects/Rockchip/packages/linux/patches/RK3566/0003-drm-panel-simple-Read-panel-orientation.patch b/projects/Rockchip/packages/linux/patches/RK3566/0003-drm-panel-simple-Read-panel-orientation.patch new file mode 100644 index 0000000000..c76a3747d4 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RK3566/0003-drm-panel-simple-Read-panel-orientation.patch @@ -0,0 +1,55 @@ +From 953791baf27ea161378af5c78d8db337472507c8 Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Fri, 14 Aug 2020 00:56:09 +0300 +Subject: [PATCH 3/4] drm/panel-simple: Read panel orientation + +The panel orientation needs to parsed from a device-tree and assigned to +the panel's connector in order to make orientation property available to +userspace. That's what this patch does for the panel-simple driver. + +Signed-off-by: Dmitry Osipenko +Signed-off-by: Sam Ravnborg +Link: https://patchwork.freedesktop.org/patch/msgid/20200813215609.28643-5-digetx@gmail.com +--- + drivers/gpu/drm/panel/panel-simple.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c +index f41d4e091..f10181b93 100644 +--- a/drivers/gpu/drm/panel/panel-simple.c ++++ b/drivers/gpu/drm/panel/panel-simple.c +@@ -127,6 +127,8 @@ struct panel_simple { + struct gpio_desc *spi_scl_gpio; + struct gpio_desc *spi_cs_gpio; + struct device_node *np_crtc; ++ ++ enum drm_panel_orientation orientation; + }; + + enum rockchip_cmd_type { +@@ -442,6 +444,9 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel) + if (panel->desc->bus_flags) + connector->display_info.bus_flags = panel->desc->bus_flags; + ++ /* set up connector's "panel orientation" property */ ++ drm_connector_set_panel_orientation(connector, panel->orientation); ++ + return num; + } + +@@ -789,6 +794,12 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) + return -EPROBE_DEFER; + } + ++ err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation); ++ if (err) { ++ dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err); ++ return err; ++ } ++ + ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0); + if (ddc) { + panel->ddc = of_find_i2c_adapter_by_node(ddc); +-- +2.34.1 + diff --git a/projects/Rockchip/packages/u-boot/patches/RK3326/001-add-rg351x.patch b/projects/Rockchip/packages/u-boot/patches/RK3326/001-add-rg351x.patch index ab06fc5d70..36ff9a08a6 100644 --- a/projects/Rockchip/packages/u-boot/patches/RK3326/001-add-rg351x.patch +++ b/projects/Rockchip/packages/u-boot/patches/RK3326/001-add-rg351x.patch @@ -10,10 +10,10 @@ diff -rupN uboot.orig/cmd/hwrev.c uboot/cmd/hwrev.c + env_set("hwrev", "rg351v"); + env_set("dtb_name", "rk3326-anbernic-rg351v.dtb"); + } -+ /* RG351MP */ ++ /* R33S */ + else if (check_range(140, 190, hwrev_adc)) { -+ env_set("hwrev", "rg351mp"); -+ env_set("dtb_name", "rk3326-anbernic-rg351mp.dtb"); ++ env_set("hwrev", "r33s"); ++ env_set("dtb_name", "rk3326-gameconsole-r33s.dtb"); + } + /* XU10 */ + else if (check_range(1000, 1050, hwrev_adc)) { diff --git a/projects/Rockchip/packages/u-boot/patches/RK3399/000-rk3399-ram.patch b/projects/Rockchip/packages/u-boot/patches/RK3399/000-rk3399-ram.patch new file mode 100644 index 0000000000..b5db554f66 --- /dev/null +++ b/projects/Rockchip/packages/u-boot/patches/RK3399/000-rk3399-ram.patch @@ -0,0 +1,12 @@ +diff -rupN u-boot.orig/arch/arm/dts/rk3399-evb.dts u-boot/arch/arm/dts/rk3399-evb.dts +--- u-boot.orig/arch/arm/dts/rk3399-evb.dts 2024-01-19 17:53:16.898246406 +0000 ++++ u-boot/arch/arm/dts/rk3399-evb.dts 2024-01-19 17:59:15.431212367 +0000 +@@ -6,6 +6,8 @@ + /dts-v1/; + #include + #include "rk3399.dtsi" ++#include "rk3399-u-boot.dtsi" ++#include "rk3399-sdram-lpddr4-100.dtsi" + + / { + model = "Rockchip RK3399 Evaluation Board";