Skip to content
Open

ipu4p #163

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
dd756e7
media: intel: Add IPU4 input and processing system drivers
Feb 26, 2026
0ffaf3c
media: intel: Add Kconfig and Makefile for IPU4 and IPU4P drivers
Mar 1, 2026
b5036a5
media: intel/ipu4: modify IPU4 related headers
Feb 26, 2026
34a25e1
media: intel/ipu4: Remove legacy crlmodule header dependency
Feb 26, 2026
7f76492
media: intel/ipu4: Remove kernel version compatibility code
Feb 26, 2026
14c4b7c
media: intel/ipu4: Fix Bayer format propagation and
Feb 26, 2026
04bef91
media: intel/ipu4: Track DMA allocations with internal VMA list
Feb 26, 2026
1ab8b85
media: v4l2: Rename CSI-2 frame descriptor fields to align with media…
Feb 26, 2026
800ef16
media: intel/ipu4: Use generic DMA API instead of PCI-specific functions
Feb 26, 2026
6ad5676
media: intel/ipu4: Update to new media pad lookup API
Feb 26, 2026
13d13a9
media: intel/ipu4: Use media_entity_pipeline() accessor function
Feb 26, 2026
3f1854f
media: intel/ipu4: Implement virtual channel aware pipeline validation
Feb 26, 2026
86cac78
media: intel/ipu4: Replace dma_buf_map with iosys_map for buffer mapping
Feb 26, 2026
10e03fa
media: intel/ipu4: Pass entity directly to media_graph_walk_start()
Feb 26, 2026
2505843
media: intel/ipu4: Integrate IPU ISYS with ipu-bridge for sensor disc…
Feb 26, 2026
aaf4e51
media: intel/ipu4: Advertise media controller capability and filter f…
Feb 26, 2026
519fce1
media: v4l2: Add descriptions for vector Bayer pixel formats
Feb 26, 2026
0029c84
media: intel/ipu4: Use multiplanar buffer type for format enumeration
Feb 26, 2026
5d8463a
media: intel/ipu4: Implement frame size enumeration (VIDIOC_ENUM_FRAM…
Feb 26, 2026
31d88fc
media: intel/ipu4: Simplify DMA buffer allocation with dma_alloc_cohe…
Feb 26, 2026
ad32759
media: intel/ipu4: Simplify DMA buffer deallocation with dma_free_coh…
Feb 26, 2026
45835b0
media: intel/ipu4: Use dma_map_sgtable helpers for scatter-gather map…
Feb 26, 2026
c6d9c06
media: intel/ipu4: Use v4l2_get_link_freq() helper for CSI-2 link fre…
Feb 26, 2026
a235cda
media: intel/ipu4: Replace strlcpy() with safer strscpy() function
Feb 26, 2026
3fb29b4
media: intel/ipu4: Use noop_llseek instead of deprecated no_llseek
Feb 26, 2026
f499075
media: intel/ipu4: Update from_timer() to timer_container_of()
Feb 26, 2026
2dc4da4
media: intel/ipu4: Update try_to_del_timer_sync() to timer_delete_syn…
Feb 26, 2026
deab1c8
media: intel/ipu4: Update get_user_pages() call to match new kernel s…
Feb 26, 2026
95700b1
media: intel/ipu4: Convert MODULE_IMPORT_NS to string literal format
Feb 26, 2026
e0a48f2
media: intel/ipu4: Update set_routing callback to match v4l2_subdev_p…
Feb 26, 2026
ec79c1e
media: intel/ipu4: Modernize user page pinning with pin_user_pages_fa…
Feb 26, 2026
a114477
media: intel/ipu4: Adapt to v4l2_get_link_freq() API signature change
Feb 26, 2026
0308b98
media: intel/ipu4: Use v4l2_async_connection for async sensor discovery
Feb 26, 2026
6950f6d
media: intel/ipu4: Update ipu_bus_match() signature for const driver …
Feb 26, 2026
ff982c0
media: intel/ipu4: Update v4l2_async_nf_init() call with v4l2_dev par…
Feb 26, 2026
810ba05
media: intel/ipu4: Adapt to v4l2_async_nf_register() API signature ch…
Feb 26, 2026
9aebbc2
media: intel/ipu4: Update to new v4l2_subdev_state pad accessors
Feb 26, 2026
307b9f7
media: v4l2-subdev: Fix invalid array indexing on routing.routes
Feb 26, 2026
5ff3c84
media: intel/ipu4: Guard cleanup against uninitialized resources
Feb 26, 2026
123f243
media: intel/ipu4: Handle uninitialized format state pointers safely
Feb 26, 2026
a63b1d6
media: intel/ipu4: Safely handle stream-aware subdevices without routing
Feb 26, 2026
ab749e7
media: intel/ipu4: Initialize pad directions before media_entity_pads…
Feb 26, 2026
98dfd17
media: intel/ipu4: Add guards for uninitialized array cleanup
Feb 26, 2026
c4b2dd4
media: intel/ipu4: Add link validation infrastructure
Feb 26, 2026
a9291eb
media: intel/ipu4: Fix format enumeration and add multiplanar format …
Feb 26, 2026
dbc6904
media: intel/ipu4: Implement format-based link validation
Feb 26, 2026
e436da0
media: intel/ipu4: Fix format table lookup priority in link_validate()
Feb 26, 2026
e9fb607
media: intel/ipu4: Count video devices for nr_queues initialization
Feb 26, 2026
6bd8a21
media: intel/ipu4: Fix IPU4P firmware port-to-array-index mapping
Feb 26, 2026
447acba
media: intel/ipu4: Expand CSI-2 ports to support Surface Pro 7
Feb 26, 2026
11a4046
media: intel/ipu4: Use fwnode_graph_for_each_endpoint() for enumeration
Feb 26, 2026
6fc5906
media: intel/ipu4: Replace polling loops with readl_poll_timeout()
Feb 26, 2026
4be7dd1
media: intel/ipu4: Retry buttress authentication on driver open
Feb 26, 2026
af5f627
media: intel/ipu4: Rename symbols to avoid IPU7 namespace collision
Feb 26, 2026
e094f90
media: intel/ipu4: Workaround to enable libcamera simple pipeline
Mar 1, 2026
b52e83d
media: intel/ipu4: Add OV5693 debug instrumentation
Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
94 changes: 92 additions & 2 deletions drivers/media/i2c/ov5693.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,46 @@ struct ov5693_device {
} ctrls;
};

static void ov5693_log_stream_state(struct ov5693_device *ov5693, const char *tag, int enable)
{
dev_dbg(ov5693->dev,
"%s: stream=%d fmt=%ux%u crop=[l=%d t=%d w=%u h=%u] binning[x=%d y=%d] inc[x_odd=%u y_odd=%u] vts=%u ctrls[vblank=%d exp=%d again=%d dgain=%d hflip=%d vflip=%d test_pattern=%d\n",
tag, enable,
ov5693->mode.format.width, ov5693->mode.format.height,
ov5693->mode.crop.left, ov5693->mode.crop.top,
ov5693->mode.crop.width, ov5693->mode.crop.height,
ov5693->mode.binning_x, ov5693->mode.binning_y,
ov5693->mode.inc_x_odd, ov5693->mode.inc_y_odd, ov5693->mode.vts,
ov5693->ctrls.vblank ? ov5693->ctrls.vblank->val : -1,
ov5693->ctrls.exposure ? ov5693->ctrls.exposure->val : -1,
ov5693->ctrls.analogue_gain ? ov5693->ctrls.analogue_gain->val : -1,
ov5693->ctrls.digital_gain ? ov5693->ctrls.digital_gain->val : -1,
ov5693->ctrls.hflip ? ov5693->ctrls.hflip->val : -1,
ov5693->ctrls.vflip ? ov5693->ctrls.vflip->val : -1,
ov5693->ctrls.test_pattern ? ov5693->ctrls.test_pattern->val : -1);
}

static void ov5693_log_hw_state(struct ov5693_device *ov5693, const char *tag)
{
u64 stream_reg;
int ret;

ret = cci_read(ov5693->regmap, OV5693_SW_STREAM_REG, &stream_reg, NULL);
if (ret) {
dev_dbg(ov5693->dev, "%s: failed to read stream reg: %d\n", tag, ret);
return;
}

dev_dbg(ov5693->dev,
"%s: stream_reg=0x%02llx hts=%u vts=%u out=%ux%u crop=[x=%u..%u y=%u..%u]\n",
tag, stream_reg, OV5693_FIXED_PPL, ov5693->mode.vts,
ov5693->mode.format.width, ov5693->mode.format.height,
ov5693->mode.crop.left,
ov5693->mode.crop.left + ov5693->mode.crop.width,
ov5693->mode.crop.top,
ov5693->mode.crop.top + ov5693->mode.crop.height);
}

static const struct cci_reg_sequence ov5693_global_regs[] = {
{CCI_REG8(0x3016), 0xf0},
{CCI_REG8(0x3017), 0xf0},
Expand Down Expand Up @@ -631,6 +671,7 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693)
{
int ret;

dev_dbg(ov5693->dev, "sensor_init: start\n");
ret = ov5693_sw_reset(ov5693);
if (ret)
return dev_err_probe(ov5693->dev, ret,
Expand All @@ -643,31 +684,41 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693)
"global settings error\n");

ret = ov5693_mode_configure(ov5693);
if (!ret)
ov5693_log_stream_state(ov5693, "sensor_init configured mode", 0);
if (ret)
return dev_err_probe(ov5693->dev, ret,
"mode configure error\n");

ret = ov5693_enable_streaming(ov5693, false);
if (ret)
dev_err(ov5693->dev, "stop streaming error\n");
else
ov5693_log_hw_state(ov5693, "sensor_init stream-off");

return ret;
}

static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
{
dev_dbg(ov5693->dev, "powerdown: reset-gpio=%d powerdown-gpio=%d\n",
ov5693->reset ? 1 : 0, ov5693->powerdown ? 1 : 0);
gpiod_set_value_cansleep(ov5693->reset, 1);
gpiod_set_value_cansleep(ov5693->powerdown, 1);

regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);

clk_disable_unprepare(ov5693->xvclk);
dev_dbg(ov5693->dev, "powerdown: done\n");
}

static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
{
int ret;
unsigned long xvclk_rate = clk_get_rate(ov5693->xvclk);

dev_dbg(ov5693->dev, "powerup: xvclk=%lu reset-gpio=%d powerdown-gpio=%d\n",
xvclk_rate, ov5693->reset ? 1 : 0, ov5693->powerdown ? 1 : 0);
gpiod_set_value_cansleep(ov5693->reset, 1);
gpiod_set_value_cansleep(ov5693->powerdown, 1);

Expand All @@ -683,11 +734,13 @@ static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
goto fail_power;
}

dev_dbg(ov5693->dev, "powerup: regulators enabled (avdd,dovdd,dvdd)\n");
gpiod_set_value_cansleep(ov5693->powerdown, 0);
gpiod_set_value_cansleep(ov5693->reset, 0);

usleep_range(5000, 7500);

dev_dbg(ov5693->dev, "powerup: done\n");
return 0;

fail_power:
Expand Down Expand Up @@ -738,6 +791,9 @@ static int ov5693_detect(struct ov5693_device *ov5693)
u64 id;

ret = cci_read(ov5693->regmap, OV5693_REG_CHIP_ID, &id, NULL);
dev_dbg(ov5693->dev,
"detect: chip-id read ret=%d id=0x%04llx expected=0x%04x\n",
ret, id, OV5693_CHIP_ID);
if (ret)
return ret;

Expand Down Expand Up @@ -970,33 +1026,54 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
int ret;

dev_dbg(ov5693->dev, "s_stream: request enable=%d\n",
enable);
ov5693_log_stream_state(ov5693, "s_stream pre", enable);

if (enable) {
ret = pm_runtime_resume_and_get(ov5693->dev);
if (ret)
if (ret) {
dev_err(ov5693->dev,
"s_stream: pm_runtime_resume_and_get failed: %d\n",
ret);
return ret;
}

mutex_lock(&ov5693->lock);
ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler);
if (ret) {
dev_err(ov5693->dev, "s_stream: ctrl setup failed: %d\n", ret);
mutex_unlock(&ov5693->lock);
goto err_power_down;
}

ret = ov5693_enable_streaming(ov5693, true);
dev_dbg(ov5693->dev, "s_stream: stream-on register write ret=%d\n",
ret);
if (!ret)
ov5693_log_hw_state(ov5693, "s_stream stream-on");
mutex_unlock(&ov5693->lock);
} else {
mutex_lock(&ov5693->lock);
ret = ov5693_enable_streaming(ov5693, false);
dev_dbg(ov5693->dev, "s_stream: stream-off register write ret=%d\n",
ret);
if (!ret)
ov5693_log_hw_state(ov5693, "s_stream stream-off");
mutex_unlock(&ov5693->lock);
}
if (ret)
goto err_power_down;

ov5693_log_stream_state(ov5693, "s_stream post", enable);

if (!enable)
pm_runtime_put(ov5693->dev);

return 0;
err_power_down:
dev_err(ov5693->dev, "s_stream: failed enable=%d ret=%d\n",
enable, ret);
pm_runtime_put_noidle(ov5693->dev);
return ret;
}
Expand Down Expand Up @@ -1236,6 +1313,11 @@ static int ov5693_check_hwcfg(struct ov5693_device *ov5693)
if (ret)
return ret;

dev_dbg(ov5693->dev,
"check_hwcfg: lanes=%u nr_of_link_frequencies=%u\n",
bus_cfg.bus.mipi_csi2.num_data_lanes,
bus_cfg.nr_of_link_frequencies);

if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
dev_err(ov5693->dev, "only a 2-lane CSI2 config is supported");
ret = -EINVAL;
Expand All @@ -1248,9 +1330,13 @@ static int ov5693_check_hwcfg(struct ov5693_device *ov5693)
goto out_free_bus_cfg;
}

for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
dev_dbg(ov5693->dev,
"check_hwcfg: link_frequencies[%u]=%lld\n",
i, bus_cfg.link_frequencies[i]);
if (bus_cfg.link_frequencies[i] == OV5693_LINK_FREQ_419_2MHZ)
break;
}

if (i == bus_cfg.nr_of_link_frequencies) {
dev_err(ov5693->dev, "supported link freq %ull not found\n",
Expand Down Expand Up @@ -1285,6 +1371,8 @@ static int ov5693_probe(struct i2c_client *client)
if (ret)
return ret;

dev_dbg(&client->dev, "probe: hwcfg validated\n");

mutex_init(&ov5693->lock);

v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
Expand Down Expand Up @@ -1340,6 +1428,8 @@ static int ov5693_probe(struct i2c_client *client)
if (ret)
goto err_powerdown;

dev_dbg(&client->dev, "probe: sensor detected and runtime-pm setup starting\n");

pm_runtime_set_active(&client->dev);
pm_runtime_get_noresume(&client->dev);
pm_runtime_enable(&client->dev);
Expand Down
64 changes: 64 additions & 0 deletions drivers/media/pci/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,67 @@ config IPU_BRIDGE
- Microsoft Surface models (except Surface Pro 3)
- The Lenovo Miix line (for example the 510, 520, 710 and 720)
- Dell 7285

config VIDEO_INTEL_IPU
tristate "Intel IPU driver"
depends on ACPI
select IOMMU_API
select IOMMU_IOVA
select X86_DEV_DMA_OPS if X86
select VIDEOBUF2_DMA_CONTIG
select PHYS_ADDR_T_64BIT
select COMMON_CLK
help
Main driver for Intel Image Processing Unit. Say Y here.

choice
prompt "Intel IPU generation type"
depends on VIDEO_INTEL_IPU
default VIDEO_INTEL_IPU4P

config VIDEO_INTEL_IPU4
bool "Compile for IPU4 driver"
help
Select IPU4 for Intel Apollo Lake (PCI ID 8086:5a88):
Celeron N3350, Pentium N4200 or Atom E3900 Series Imaging Unit.

config VIDEO_INTEL_IPU4P
bool "Compile for IPU4P driver"
help
Select IPU4P for Intel Ice Lake (PCI ID 8086 8a19).
Supported systems include:
- Surface Pro 7
- Surface Book 3
- Surface Laptop 3
- Dell XPS 13 7390 2-in-1

endchoice

choice
prompt "Intel IPU hardware platform type"
depends on VIDEO_INTEL_IPU
default VIDEO_INTEL_IPU_SOC

config VIDEO_INTEL_IPU_SOC
bool "Compile for SOC"
help
Select for SOC platform

endchoice

config VIDEO_INTEL_IPU_FW_LIB
bool "Compile firmware library"
depends on VIDEO_INTEL_IPU
default y
help
If selected, the firmware hostlib css will be compiled

config VIDEO_INTEL_IPU_WERROR
bool "Force GCC to throw errors instead of warnings when compiling"
depends on VIDEO_INTEL_IPU
depends on EXPERT
depends on !COMPILE_TEST
default n
help
Adds -Werror to the build flags for the Intel IPU module.
Recommended for driver developers only.
13 changes: 13 additions & 0 deletions drivers/media/pci/intel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@
obj-$(CONFIG_IPU_BRIDGE) += ipu-bridge.o
obj-y += ipu3/
obj-y += ivsc/
# force check the compile warning to make sure zero warnings
# note we may have build issue when gcc upgraded.
ccflags-y := -Wno-error=uninitialized
subdir-ccflags-y += $(call cc-disable-warning, unused-parameter)
subdir-ccflags-y += $(call cc-disable-warning, implicit-fallthrough)
subdir-ccflags-y += $(call cc-disable-warning, missing-field-initializers)
subdir-ccflags-y += $(call cc-disable-warning, int-conversion)
subdir-ccflags-y += $(call cc-disable-warning, enum-conversion)
subdir-ccflags-y += $(call cc-disable-warning, uninitialized)
subdir-ccflags-$(CONFIG_VIDEO_INTEL_IPU_WERROR) += -Werror

obj-$(CONFIG_VIDEO_INTEL_IPU6) += ipu6/
obj-$(CONFIG_VIDEO_INTEL_IPU4) += ipu4/
obj-$(CONFIG_VIDEO_INTEL_IPU4P) += ipu4/
Loading