diff --git a/src/ipa/libipa/algorithm.cpp b/src/ipa/ipu3/algorithms/algorithm.cpp
similarity index 55%
rename from src/ipa/libipa/algorithm.cpp
rename to src/ipa/ipu3/algorithms/algorithm.cpp
index 930f9353..dd46846a 100644
--- a/src/ipa/libipa/algorithm.cpp
+++ b/src/ipa/ipu3/algorithms/algorithm.cpp
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2021, Ideas On Board
  *
- * algorithm.cpp - ISP control algorithms
+ * algorithm.cpp - IPU3 control algorithm interface
  */
 
 #include "algorithm.h"
@@ -14,26 +14,17 @@
 
 namespace libcamera {
 
-/**
- * \brief The IPA namespace
- *
- * The IPA namespace groups all types specific to IPA modules. It serves as the
- * top-level namespace for the IPA library libipa, and also contains
- * module-specific namespaces for IPA modules.
- */
-namespace ipa {
+namespace ipa::ipu3 {
 
 /**
  * \class Algorithm
- * \brief The base class for all IPA algorithms
+ * \brief The base class for all IPU3 algorithms
  *
  * The Algorithm class defines a standard interface for IPA algorithms. By
  * abstracting algorithms, it makes possible the implementation of generic code
  * to manage algorithms regardless of their specific type.
  */
 
-Algorithm::~Algorithm() = default;
-
-} /* namespace ipa */
+} /* namespace ipa::ipu3 */
 
 } /* namespace libcamera */
diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h
new file mode 100644
index 00000000..072f01c4
--- /dev/null
+++ b/src/ipa/ipu3/algorithms/algorithm.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Ideas On Board
+ *
+ * algorithm.h - IPU3 control algorithm interface
+ */
+#ifndef __LIBCAMERA_IPA_IPU3_ALGORITHM_H__
+#define __LIBCAMERA_IPA_IPU3_ALGORITHM_H__
+
+namespace libcamera {
+
+namespace ipa::ipu3 {
+
+class Algorithm
+{
+public:
+	virtual ~Algorithm() {}
+};
+
+} /* namespace ipa::ipu3 */
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ */
diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build
new file mode 100644
index 00000000..dc538b79
--- /dev/null
+++ b/src/ipa/ipu3/algorithms/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: CC0-1.0
+
+ipu3_ipa_algorithms = files([
+    'algorithm.cpp',
+])
diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h
index 9f3d4257..f00b98d6 100644
--- a/src/ipa/ipu3/ipu3_agc.h
+++ b/src/ipa/ipu3/ipu3_agc.h
@@ -13,7 +13,7 @@
 
 #include <libcamera/geometry.h>
 
-#include "libipa/algorithm.h"
+#include "algorithms/algorithm.h"
 
 namespace libcamera {
 
diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h
index 122cf68c..ea2d4320 100644
--- a/src/ipa/ipu3/ipu3_awb.h
+++ b/src/ipa/ipu3/ipu3_awb.h
@@ -13,7 +13,7 @@
 
 #include <libcamera/geometry.h>
 
-#include "libipa/algorithm.h"
+#include "algorithms/algorithm.h"
 
 namespace libcamera {
 
diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build
index b6364190..fcb27d68 100644
--- a/src/ipa/ipu3/meson.build
+++ b/src/ipa/ipu3/meson.build
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: CC0-1.0
 
+subdir('algorithms')
+
 ipa_name = 'ipa_ipu3'
 
 ipu3_ipa_sources = files([
@@ -8,6 +10,8 @@ ipu3_ipa_sources = files([
     'ipu3_awb.cpp',
 ])
 
+ipu3_ipa_sources += ipu3_ipa_algorithms
+
 mod = shared_module(ipa_name,
                     [ipu3_ipa_sources, libcamera_generated_ipa_headers],
                     name_prefix : '',
diff --git a/src/ipa/libipa/algorithm.h b/src/ipa/libipa/algorithm.h
deleted file mode 100644
index 89cee4c4..00000000
--- a/src/ipa/libipa/algorithm.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2021, Ideas On Board
- *
- * algorithm.h - ISP control algorithm interface
- */
-#ifndef __LIBCAMERA_IPA_LIBIPA_ALGORITHM_H__
-#define __LIBCAMERA_IPA_LIBIPA_ALGORITHM_H__
-
-namespace libcamera {
-
-namespace ipa {
-
-class Algorithm
-{
-public:
-	virtual ~Algorithm();
-};
-
-} /* namespace ipa */
-
-} /* namespace libcamera */
-
-#endif /* __LIBCAMERA_IPA_LIBIPA_ALGORITHM_H__ */
diff --git a/src/ipa/libipa/libipa.cpp b/src/ipa/libipa/libipa.cpp
new file mode 100644
index 00000000..08bc3541
--- /dev/null
+++ b/src/ipa/libipa/libipa.cpp
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Ideas On Board
+ *
+ * libipa.cpp - libipa interface
+ */
+
+namespace libcamera {
+
+/**
+ * \brief The IPA namespace
+ *
+ * The IPA namespace groups all types specific to IPA modules. It serves as the
+ * top-level namespace for the IPA library libipa, and also contains
+ * module-specific namespaces for IPA modules.
+ */
+namespace ipa {
+
+} /* namespace ipa */
+
+} /* namespace libcamera */
+
diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build
index 3fda7c00..4d073a03 100644
--- a/src/ipa/libipa/meson.build
+++ b/src/ipa/libipa/meson.build
@@ -1,15 +1,14 @@
 # SPDX-License-Identifier: CC0-1.0
 
 libipa_headers = files([
-    'algorithm.h',
     'camera_sensor_helper.h',
     'histogram.h'
 ])
 
 libipa_sources = files([
-    'algorithm.cpp',
     'camera_sensor_helper.cpp',
-    'histogram.cpp'
+    'histogram.cpp',
+    'libipa.cpp',
 ])
 
 libipa_includes = include_directories('..')
