diff --git a/nixos/modules/hardware/video/webcam/ipu7.nix b/nixos/modules/hardware/video/webcam/ipu7.nix new file mode 100644 index 0000000000000..ff5fcc7d7dc59 --- /dev/null +++ b/nixos/modules/hardware/video/webcam/ipu7.nix @@ -0,0 +1,84 @@ +{ + config, + lib, + pkgs, + ... +}: +let + + inherit (lib) + mkDefault + mkEnableOption + mkIf + mkOption + optional + types + ; + + cfg = config.hardware.ipu7; + +in +{ + + options.hardware.ipu7 = { + + enable = mkEnableOption "support for Intel IPU7/MIPI cameras"; + + platform = mkOption { + type = types.enum [ + "ipu7x" + "ipu75xa" + ]; + description = '' + Choose the version for your hardware platform. The IPU reports which one + it is through its PCI ID, visible as the Multimedia controller in lspci. + + - ipu7x (Lunar Lake, PCI 8086:645d) + Sensor list: https://github.com/intel/ipu7-camera-hal/tree/main/config/linux/ipu7x/sensors + - ipu75xa (Panther Lake, PCI 8086:b05d) + Sensor list: https://github.com/intel/ipu7-camera-hal/tree/main/config/linux/ipu75xa/sensors + ''; + }; + + }; + + config = mkIf cfg.enable { + + # Kernels >= 6.17 ship an IPU7 core and ISys in drivers/staging/media/ipu7, + # but no PSys, so they cannot drive the hardware ISP that the camera HAL + # needs. ipu7-drivers supplies just the PSys module (intel-ipu7-psys), which + # has no in-tree counterpart, and links it against the in-tree core and ISys + # that already enumerate the sensor. + boot.extraModulePackages = with config.boot.kernelPackages; [ + ipu7-drivers + ]; + + hardware.firmware = with pkgs; [ + ipu7-camera-bins + ivsc-firmware + ]; + + services.udev.extraRules = '' + SUBSYSTEM=="intel-ipu7-psys", MODE="0660", GROUP="video" + ''; + + services.v4l2-relayd.instances.ipu7 = { + enable = mkDefault true; + + cardLabel = mkDefault "Intel MIPI Camera"; + + extraPackages = + with pkgs.gst_all_1; + [ ] + ++ optional (cfg.platform == "ipu7x") icamerasrc-ipu7x + ++ optional (cfg.platform == "ipu75xa") icamerasrc-ipu75xa; + + input = { + pipeline = "icamerasrc"; + # REVIEW from https://edc.intel.com/content/www/us/en/secure/design/confidential/products/platforms/details/lunar-lake-mx/core-ultra-200v-series-processors-datasheet-volume-1-of-2/camera-integrated-isp/ + # Output Formats - NV12, NV16, I420, M420, YUY2, YUYV, P010, P016 + format = "NV12"; + }; + }; + }; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index a1c6cedf8a419..5d0d3a7ef591b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -129,6 +129,7 @@ ./hardware/video/virtualbox.nix ./hardware/video/webcam/facetimehd.nix ./hardware/video/webcam/ipu6.nix + ./hardware/video/webcam/ipu7.nix ./hardware/wooting.nix ./hardware/xone.nix ./hardware/xpad-noone.nix diff --git a/pkgs/by-name/ip/ipu7-camera-bins/package.nix b/pkgs/by-name/ip/ipu7-camera-bins/package.nix new file mode 100644 index 0000000000000..773e99ce6cb48 --- /dev/null +++ b/pkgs/by-name/ip/ipu7-camera-bins/package.nix @@ -0,0 +1,78 @@ +{ + lib, + stdenv, + fetchFromGitHub, + autoPatchelfHook, + expat, + zlib, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "ipu7-camera-bins"; + version = "20260629_1"; + + src = fetchFromGitHub { + repo = "ipu7-camera-bins"; + owner = "intel"; + rev = finalAttrs.version; + hash = "sha256-LjiqxlQKDLArgK2puxlyTpLPtL6QN6P/xWO2asPTLig="; + }; + + __structuredAttrs = true; + strictDeps = true; + + nativeBuildInputs = [ + autoPatchelfHook + ]; + + buildInputs = [ + (lib.getLib stdenv.cc.cc) + expat + zlib + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out + cp --no-preserve=mode --recursive \ + lib \ + include \ + $out/ + + # REVIEW file exists now + # There is no LICENSE file in the src + # install -m 0644 -D LICENSE $out/share/doc/LICENSE + + runHook postInstall + ''; + + postFixup = '' + for lib in $out/lib/lib*.so.*; do \ + lib=''${lib##*/}; \ + target=$out/lib/''${lib%.*}; \ + if [ ! -e "$target" ]; then \ + ln -s "$lib" "$target"; \ + fi \ + done + + for pcfile in $out/lib/pkgconfig/*.pc; do + substituteInPlace $pcfile \ + --replace 'prefix=/usr' "prefix=$out" + done + ''; + + meta = with lib; { + description = "IPU firmware and proprietary image processing libraries"; + homepage = "https://github.com/intel/ipu7-camera-bins"; + license = licenses.issl; + sourceProvenance = with sourceTypes; [ + binaryFirmware + ]; + maintainers = [ + lib.maintainers.aoli-al + lib.maintainers.pseudocc + ]; + platforms = [ "x86_64-linux" ]; + }; +}) diff --git a/pkgs/by-name/ip/ipu7x-camera-hal/package.nix b/pkgs/by-name/ip/ipu7x-camera-hal/package.nix new file mode 100644 index 0000000000000..6fdb1999e7b45 --- /dev/null +++ b/pkgs/by-name/ip/ipu7x-camera-hal/package.nix @@ -0,0 +1,110 @@ +{ + lib, + stdenv, + fetchFromGitHub, + + # build + cmake, + pkg-config, + + # runtime + expat, + ipu7-camera-bins, + jsoncpp, + libtool, + gst_all_1, + libdrm, + + # Pick one of + # - ipu7x (Lunar Lake) + # - ipu75xa (Lunar Lake) + ipuVersion ? "ipu7x", +}: +let + ipuTarget = + { + "ipu7x" = "ipu_lnl"; + "ipu75xa" = "ipu_lnl"; + } + .${ipuVersion}; +in +stdenv.mkDerivation (finalAttrs: { + pname = "${ipuVersion}-camera-hal"; + version = "20260629_1"; + + src = fetchFromGitHub { + owner = "intel"; + repo = "ipu7-camera-hal"; + rev = finalAttrs.version; + hash = "sha256-uiVPQBMHUBP9ZFzX0QMimIpgbmvm7JLTkD588V07iGw="; + }; + + __structuredAttrs = true; + strictDeps = true; + + nativeBuildInputs = [ + cmake + pkg-config + ]; + + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Release" + "-DCMAKE_INSTALL_PREFIX=${placeholder "out"}" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_POLICY_VERSION_MINIMUM=3.5" + "-DBUILD_CAMHAL_ADAPTOR=ON" + "-DBUILD_CAMHAL_PLUGIN=ON" + "-DIPU_VERSIONS=${ipuVersion}" + "-DUSE_STATIC_GRAPH=ON" + "-DUSE_STATIC_GRAPH_AUTOGEN=ON" + ]; + + env.NIX_CFLAGS_COMPILE = "-Wno-error"; + + enableParallelBuilding = true; + + buildInputs = [ + expat + ipu7-camera-bins + jsoncpp + libtool + gst_all_1.gstreamer + gst_all_1.gst-plugins-base + libdrm + ]; + + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-fail 'set (CMAKE_CXX_STANDARD 11)' \ + 'set (CMAKE_CXX_STANDARD 17)' + substituteInPlace src/platformdata/JsonParserBase.h \ + --replace-fail '' '' + ''; + + postInstall = '' + mkdir -p $out/include/${ipuTarget}/ + cp -r $src/include $out/include/${ipuTarget}/libcamhal + ''; + + postFixup = '' + for lib in $out/lib/*.so; do + patchelf --add-rpath "${ipu7-camera-bins}/lib" $lib + done + ''; + + passthru = { + inherit ipuVersion ipuTarget; + }; + + meta = with lib; { + description = "HAL for processing of images in userspace"; + homepage = "https://github.com/intel/ipu7-camera-hal"; + license = licenses.asl20; + maintainers = [ + lib.maintainers.aoli-al + lib.maintainers.pseudocc + ]; + platforms = [ "x86_64-linux" ]; + }; +}) diff --git a/pkgs/development/libraries/gstreamer/default.nix b/pkgs/development/libraries/gstreamer/default.nix index 21712e04da55f..33195e8dec018 100644 --- a/pkgs/development/libraries/gstreamer/default.nix +++ b/pkgs/development/libraries/gstreamer/default.nix @@ -5,6 +5,7 @@ apple-sdk, ipu6ep-camera-hal, ipu6epmtl-camera-hal, + ipu75xa-camera-hal, }: lib.makeScope newScope ( @@ -45,6 +46,14 @@ lib.makeScope newScope ( ipu6-camera-hal = ipu6epmtl-camera-hal; }; + icamerasrc-ipu7x = callPackage ./icamerasrc { + ipuVariant = "ipu7"; + }; + icamerasrc-ipu75xa = callPackage ./icamerasrc { + ipuVariant = "ipu7"; + ipu7x-camera-hal = ipu75xa-camera-hal; + }; + # note: gst-python is in ../../python-modules/gst-python - called under python3Packages } // lib.optionalAttrs config.allowAliases { diff --git a/pkgs/development/libraries/gstreamer/icamerasrc/default.nix b/pkgs/development/libraries/gstreamer/icamerasrc/default.nix index 9bd3f34d49da2..aaa0ca27cbb7d 100644 --- a/pkgs/development/libraries/gstreamer/icamerasrc/default.nix +++ b/pkgs/development/libraries/gstreamer/icamerasrc/default.nix @@ -6,13 +6,22 @@ pkg-config, gst_all_1, ipu6-camera-hal, + ipu7x-camera-hal, + ipuVariant ? "ipu6", libdrm, libva, apple-sdk_gstreamer, }: - +let + ipu-camera-hal = + { + ipu6 = ipu6-camera-hal; + ipu7 = ipu7x-camera-hal; + } + .${ipuVariant}; +in stdenv.mkDerivation { - pname = "icamerasrc-${ipu6-camera-hal.ipuVersion}"; + pname = "icamerasrc-${ipu-camera-hal.ipuVersion}"; version = "unstable-2025-12-26"; src = fetchFromGitHub { @@ -28,10 +37,7 @@ stdenv.mkDerivation { ]; preConfigure = '' - # https://github.com/intel/ipu6-camera-hal/issues/1 export CHROME_SLIM_CAMHAL=ON - # https://github.com/intel/icamerasrc/issues/22 - export STRIP_VIRTUAL_CHANNEL_CAMHAL=ON ''; separateDebugInfo = true; @@ -39,11 +45,15 @@ stdenv.mkDerivation { __structuredAttrs = true; strictDeps = true; + configureFlags = [ + "--enable-gstdrmformat=yes" + ]; + buildInputs = [ gst_all_1.gstreamer gst_all_1.gst-plugins-base gst_all_1.gst-plugins-bad - ipu6-camera-hal + ipu-camera-hal libdrm libva ] @@ -60,11 +70,11 @@ stdenv.mkDerivation { enableParallelBuilding = true; passthru = { - inherit (ipu6-camera-hal) ipuVersion; + inherit (ipu-camera-hal) ipuVersion; }; meta = { - description = "GStreamer Plugin for MIPI camera support through the IPU6/IPU6EP/IPU6SE on Intel Tigerlake/Alderlake/Jasperlake platforms"; + description = "GStreamer Plugin for MIPI camera support through the IPU6/IPU7 on Intel platforms"; homepage = "https://github.com/intel/icamerasrc/tree/icamerasrc_slim_api"; license = lib.licenses.lgpl21Plus; maintainers = [ ]; diff --git a/pkgs/os-specific/linux/ipu7-drivers/default.nix b/pkgs/os-specific/linux/ipu7-drivers/default.nix new file mode 100644 index 0000000000000..95ecddab7271d --- /dev/null +++ b/pkgs/os-specific/linux/ipu7-drivers/default.nix @@ -0,0 +1,64 @@ +{ + lib, + stdenv, + fetchFromGitHub, + fetchpatch, + kernel, + kernelModuleMakeFlags, +}: + +stdenv.mkDerivation { + pname = "ipu7-drivers"; + version = "0-unstable-2026-06-30"; + + src = fetchFromGitHub { + owner = "intel"; + repo = "ipu7-drivers"; + rev = "ba5db745b26e54abbe459e1a38ff1d22d0fe0caa"; + hash = "sha256-WvFsUhAHvQGz7SZ+MZgznCIO3B1wK/Tnfcmvlegyg+E="; + }; + + patches = [ + (fetchpatch { + name = "psys-register-bus-before-adding-the-psys-device.patch"; + # https://github.com/intel/ipu7-drivers/pull/87 + url = "https://github.com/intel/ipu7-drivers/commit/77e3a0065697314cc7437a6eefd7e0d36ab06a4b.patch"; + hash = "sha256-9wz+t4w94ymx4Ro634mIgRNAhaPj1Di514h2KRBljMU="; + }) + (fetchpatch { + name = "guard-ipu7_dir-for-in-tree-core-builds.patch"; + # https://github.com/intel/ipu7-drivers/pull/88 + url = "https://github.com/intel/ipu7-drivers/commit/61ace27b1409a15a7e22f959277c256690f10a31.patch"; + hash = "sha256-7UYUUqRXOLAmGNX/ymfnFjow0Xajxf3GC+ne98nBdDo="; + }) + ]; + + nativeBuildInputs = kernel.moduleBuildDependencies; + + makeFlags = kernelModuleMakeFlags ++ [ + "KERNELRELEASE=${kernel.modDirVersion}" + "KERNEL_SRC=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + ]; + + enableParallelBuilding = true; + + preInstall = '' + sed -i -e "s,INSTALL_MOD_DIR=,INSTALL_MOD_PATH=$out INSTALL_MOD_DIR=," Makefile + ''; + + installTargets = [ + "modules_install" + ]; + + meta = { + homepage = "https://github.com/intel/ipu7-drivers"; + description = "IPU7 kernel driver"; + license = lib.licenses.gpl2Only; + maintainers = [ + lib.maintainers.aoli-al + lib.maintainers.pseudocc + ]; + platforms = [ "x86_64-linux" ]; + broken = kernel.kernelOlder "6.12"; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a2db520586a21..d8cb63c08cce9 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7817,6 +7817,10 @@ with pkgs; ipuVersion = "ipu6epmtl"; }; + ipu75xa-camera-hal = ipu7x-camera-hal.override { + ipuVersion = "ipu75xa"; + }; + iputils = hiPrio (callPackage ../os-specific/linux/iputils { }); # hiPrio for collisions with inetutils (ping) diff --git a/pkgs/top-level/linux-kernels.nix b/pkgs/top-level/linux-kernels.nix index e6ca68d1640bc..5e8cc72632ee0 100644 --- a/pkgs/top-level/linux-kernels.nix +++ b/pkgs/top-level/linux-kernels.nix @@ -369,6 +369,8 @@ in ipu6-drivers = callPackage ../os-specific/linux/ipu6-drivers { }; + ipu7-drivers = callPackage ../os-specific/linux/ipu7-drivers { }; + ivsc-driver = callPackage ../os-specific/linux/ivsc-driver { }; ixgbevf = callPackage ../os-specific/linux/ixgbevf { };