Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,33 @@ MODSRC := $(shell pwd)
export EXTERNAL_BUILD = 1
export CONFIG_VIDEO_INTEL_IPU7 = m
export CONFIG_IPU_BRIDGE = y
export CONFIG_INTEL_IPU_ACPI = m

# Default: only build IPU7 drivers (no ACPI)
obj-y += drivers/media/pci/intel/ipu7/

# For ACPI build: add platform drivers
ifdef BUILD_INTEL_IPU_ACPI
export CONFIG_INTEL_IPU_ACPI = m
obj-y += drivers/media/platform/intel/
subdir-ccflags-$(CONFIG_INTEL_IPU_ACPI) += \
-DCONFIG_INTEL_IPU_ACPI
endif

subdir-ccflags-y += -I$(src)/include

subdir-ccflags-$(CONFIG_IPU_BRIDGE) += \
-DCONFIG_IPU_BRIDGE
subdir-ccflags-$(CONFIG_INTEL_IPU_ACPI) += \
-DCONFIG_INTEL_IPU_ACPI

subdir-ccflags-y += $(subdir-ccflags-m)

all:
$(MAKE) -C $(KERNEL_SRC) M=$(MODSRC) modules

all-acpi:
$(MAKE) BUILD_INTEL_IPU_ACPI=1 -C $(KERNEL_SRC) M=$(MODSRC) modules

modules_install:
$(MAKE) INSTALL_MOD_DIR=updates -C $(KERNEL_SRC) M=$(MODSRC) modules_install

clean:
$(MAKE) -C $(KERNEL_SRC) M=$(MODSRC) clean
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ There are 4 repositories that provide the complete setup:


## Content of this repository
- IPU7 kernel driver
- IPU7 kernel driver (support IPU8 by adding KCFLAGS="-DIPU8_INSYS_NEW_ABI" to make command)
- Kernel patches needed

## Dependencies
Expand All @@ -26,7 +26,7 @@ Three ways are available:
3. Build and install by dkms (DKMS build)

### 1. In-tree build
- Tested with kernel v6.8 and v6.10
- Tested with kernel v6.8 to v6.17
1. Check out kernel source code
2. Patch kernel source code, using patches under `patch/<kernel-version>` and `patch/<kernel-version>/in-tree-build` depending on what you need.
3. Copy `drivers` and `include` folders to kernel source code.
Expand Down
57 changes: 37 additions & 20 deletions dkms.conf
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
PACKAGE_NAME=ipu7-drivers
PACKAGE_VERSION=0.0.0

MAKE="make KERNELRELEASE=$kernelver KERNEL_SRC=$kernel_source_dir"
# Use BUILD_INTEL_IPU_ACPI environment variable to control ACPI module build
if [ -n "$BUILD_INTEL_IPU_ACPI" ]; then
MAKE="make BUILD_INTEL_IPU_ACPI=1 all-acpi KERNELRELEASE=$kernelver KERNEL_SRC=$kernel_source_dir"
else
MAKE="make KERNELRELEASE=$kernelver KERNEL_SRC=$kernel_source_dir"
fi
CLEAN="make KERNELRELEASE=$kernelver KERNEL_SRC=$kernel_source_dir clean"
AUTOINSTALL="yes"

Expand Down Expand Up @@ -31,28 +36,40 @@ version_lt() {
KERNEL_VERSION=$(echo ${kernelver} | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
KV_IPU7_ISYS=6.17.0

BUILT_MODULE_NAME[0]="ipu-acpi"
BUILT_MODULE_LOCATION[0]="drivers/media/platform/intel"
DEST_MODULE_LOCATION[0]="/updates"
MODULE_INDEX=0

BUILT_MODULE_NAME[1]="ipu-acpi-pdata"
BUILT_MODULE_LOCATION[1]="drivers/media/platform/intel"
DEST_MODULE_LOCATION[1]="/updates"
# Default modules: intel-ipu7 family
if version_lt ${KERNEL_VERSION} ${KV_IPU7_ISYS}; then
BUILT_MODULE_NAME[$MODULE_INDEX]="intel-ipu7"
BUILT_MODULE_LOCATION[$MODULE_INDEX]="drivers/media/pci/intel/ipu7"
DEST_MODULE_LOCATION[$MODULE_INDEX]="/updates"
MODULE_INDEX=$((MODULE_INDEX + 1))

BUILT_MODULE_NAME[2]="ipu-acpi-common"
BUILT_MODULE_LOCATION[2]="drivers/media/platform/intel"
DEST_MODULE_LOCATION[2]="/updates"
BUILT_MODULE_NAME[$MODULE_INDEX]="intel-ipu7-isys"
BUILT_MODULE_LOCATION[$MODULE_INDEX]="drivers/media/pci/intel/ipu7"
DEST_MODULE_LOCATION[$MODULE_INDEX]="/updates"
MODULE_INDEX=$((MODULE_INDEX + 1))
fi

BUILT_MODULE_NAME[3]="intel-ipu7-psys"
BUILT_MODULE_LOCATION[3]="drivers/media/pci/intel/ipu7/psys"
DEST_MODULE_LOCATION[3]="/updates"
BUILT_MODULE_NAME[$MODULE_INDEX]="intel-ipu7-psys"
BUILT_MODULE_LOCATION[$MODULE_INDEX]="drivers/media/pci/intel/ipu7/psys"
DEST_MODULE_LOCATION[$MODULE_INDEX]="/updates"
MODULE_INDEX=$((MODULE_INDEX + 1))

if version_lt ${KERNEL_VERSION} ${KV_IPU7_ISYS}; then
BUILT_MODULE_NAME[4]="intel-ipu7"
BUILT_MODULE_LOCATION[4]="drivers/media/pci/intel/ipu7"
DEST_MODULE_LOCATION[4]="/updates"
# Additional ACPI modules if BUILD_INTEL_IPU_ACPI is set
if [ -n "$BUILD_INTEL_IPU_ACPI" ]; then
BUILT_MODULE_NAME[$MODULE_INDEX]="ipu-acpi"
BUILT_MODULE_LOCATION[$MODULE_INDEX]="drivers/media/platform/intel"
DEST_MODULE_LOCATION[$MODULE_INDEX]="/updates"
MODULE_INDEX=$((MODULE_INDEX + 1))

BUILT_MODULE_NAME[$MODULE_INDEX]="ipu-acpi-pdata"
BUILT_MODULE_LOCATION[$MODULE_INDEX]="drivers/media/platform/intel"
DEST_MODULE_LOCATION[$MODULE_INDEX]="/updates"
MODULE_INDEX=$((MODULE_INDEX + 1))

BUILT_MODULE_NAME[5]="intel-ipu7-isys"
BUILT_MODULE_LOCATION[5]="drivers/media/pci/intel/ipu7"
DEST_MODULE_LOCATION[5]="/updates"
BUILT_MODULE_NAME[$MODULE_INDEX]="ipu-acpi-common"
BUILT_MODULE_LOCATION[$MODULE_INDEX]="drivers/media/platform/intel"
DEST_MODULE_LOCATION[$MODULE_INDEX]="/updates"
MODULE_INDEX=$((MODULE_INDEX + 1))
fi
16 changes: 10 additions & 6 deletions drivers/media/pci/intel/ipu7/abi/ipu7_fw_boot_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,18 @@ struct ia_gofo_secondary_boot_config {
#define IA_GOFO_DOUBLE_EXCEPTION_ERR 0xdead0806U
#define IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR 0xdead1000U
#define IA_GOFO_BIST_DATA_INTEGRITY_FAILURE 0xdead1010U

#define IA_GOFO_BOOT_STATE_UNINIT 0x57a7e000U
#define IA_GOFO_BOOT_STATE_STARTING_0 0x57a7d000U
#define IA_GOFO_BOOT_STATE_CACHE_INIT_DONE 0x57a7d010U
#define IA_GOFO_BOOT_STATE_MEM_INIT_DONE 0x57a7d020U
#define IA_GOFO_BOOT_STATE_STACK_INIT_DONE 0x57a7d030U
enum ia_gofo_boot_state {
IA_GOFO_FW_BOOT_STATE_SECONDARY_BOOT_CONFIG_READY = 0x57a7b000U,
IA_GOFO_FW_BOOT_STATE_UNINIT = 0x57a7e000U,
IA_GOFO_FW_BOOT_STATE_STARTING_0 = 0x57a7d000U,
IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = 0x57a7d010U,
IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = 0x57a7d020U,
IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = 0x57a7d030U,
IA_GOFO_FW_BOOT_STATE_UNINIT = IA_GOFO_BOOT_STATE_UNINIT,
IA_GOFO_FW_BOOT_STATE_STARTING_0 = IA_GOFO_BOOT_STATE_STARTING_0,
IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = IA_GOFO_BOOT_STATE_CACHE_INIT_DONE,
IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = IA_GOFO_BOOT_STATE_MEM_INIT_DONE,
IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = IA_GOFO_BOOT_STATE_STACK_INIT_DONE,
IA_GOFO_FW_BOOT_STATE_EARLY_BOOT_DONE = 0x57a7d100U,
IA_GOFO_FW_BOOT_STATE_BOOT_CONFIG_START = 0x57a7d200U,
IA_GOFO_FW_BOOT_STATE_QUEUE_INIT_DONE = 0x57a7d300U,
Expand Down
13 changes: 13 additions & 0 deletions drivers/media/pci/intel/ipu7/abi/ipu7_fw_isys_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,18 @@ struct ipu7_insys_resp {
struct ipu7_insys_capture_output_pin_payload pin;
struct ia_gofo_msg_err error_info;
u32 timestamp[2];
#ifdef IPU8_INSYS_NEW_ABI
u16 mipi_fn;
#endif
u8 type;
u8 msg_link_streaming_mode;
u8 stream_id;
u8 pin_id;
u8 frame_id;
u8 skip_frame;
#ifndef IPU8_INSYS_NEW_ABI
u16 mipi_fn;
#endif
};

struct ipu7_insys_resp_queue_token {
Expand Down Expand Up @@ -419,6 +424,14 @@ enum insys_msg_err_stream {
INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_OUTPUT = 36,
INSYS_MSG_ERR_STREAM_WIDTH_OUTPUT_SIZE = 37,
INSYS_MSG_ERR_STREAM_CLOSED = 38,
#ifdef IPU8_INSYS_NEW_ABI
INSYS_MSG_ERR_STREAM_BINNING_FACTOR_NOT_SUPPORTED = 39,
INSYS_MSG_ERR_STREAM_CFA_DIM_NOT_SUPPORTED = 40,
INSYS_MSG_ERR_STREAM_INVALID_UPIPE_ENABLE = 41,
INSYS_MSG_ERR_STREAM_INVALID_UPIPE_UOB_SINGLE = 42,
INSYS_MSG_ERR_STREAM_INVALID_UPIPE_UOB_SHARED = 43,
INSYS_MSG_ERR_STREAM_INVALID_UPIPE_OPAQUE_PIN_CFG = 44,
#endif
INSYS_MSG_ERR_STREAM_N
};

Expand Down
12 changes: 10 additions & 2 deletions drivers/media/pci/intel/ipu7/ipu7-buttress.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,22 @@ irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr)
u32 disable_irqs = 0;
u32 irq_status;
unsigned int i;
int active;

pm_runtime_get_noresume(dev);
active = pm_runtime_get_if_active(dev);
if (active <= 0)
return IRQ_NONE;

pb_irq = readl(isp->pb_base + INTERRUPT_STATUS);
writel(pb_irq, isp->pb_base + INTERRUPT_STATUS);

/* check btrs ATS, CFI and IMR errors, BIT(0) is unused for IPU */
pb_local_irq = readl(isp->pb_base + BTRS_LOCAL_INTERRUPT_MASK);
if (WARN_ON_ONCE(pb_local_irq == 0xffffffff)) {
pm_runtime_put_noidle(dev);
return IRQ_NONE;
}

if (pb_local_irq & ~BIT(0)) {
dev_warn(dev, "PB interrupt status 0x%x local 0x%x\n", pb_irq,
pb_local_irq);
Expand All @@ -366,7 +374,7 @@ irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr)
}

irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS);
if (!irq_status) {
if (!irq_status || WARN_ON_ONCE(irq_status == 0xffffffff)) {
pm_runtime_put_noidle(dev);
return IRQ_NONE;
}
Expand Down
6 changes: 4 additions & 2 deletions drivers/media/pci/intel/ipu7/ipu7-isys-csi-phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ static void gpreg_write(struct ipu7_isys *isys, u32 id, u32 addr, u32 data)
{
void __iomem *isys_base = isys->pdata->base;
u32 gpreg = isys->pdata->ipdata->csi2.gpreg;
void __iomem *base = isys_base + gpreg + 0x1000 * id;
void __iomem *base = isys_base + gpreg +
isys->pdata->ipdata->csi2.gpreg_stride * id;
struct device *dev = &isys->adev->auxdev.dev;

dev_dbg(dev, "gpreg write: reg 0x%zx = data 0x%08x",
Expand Down Expand Up @@ -345,7 +346,8 @@ static int ipu7_isys_phy_ready(struct ipu7_isys *isys, u32 id)
{
void __iomem *isys_base = isys->pdata->base;
u32 gpreg_offset = isys->pdata->ipdata->csi2.gpreg;
void __iomem *gpreg = isys_base + gpreg_offset + 0x1000 * id;
void __iomem *gpreg = isys_base + gpreg_offset +
isys->pdata->ipdata->csi2.gpreg_stride * id;
struct device *dev = &isys->adev->auxdev.dev;
unsigned int i;
u32 phy_ready;
Expand Down
15 changes: 2 additions & 13 deletions drivers/media/pci/intel/ipu7/ipu7-isys-queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,14 +482,13 @@ static int ipu7_isys_link_fmt_validate(struct ipu7_isys_queue *aq)
media_pad_remote_pad_first(av->vdev.entity.pads);
struct v4l2_mbus_framefmt format;
struct v4l2_subdev *sd;
u32 r_stream, code;
u32 r_stream = 0, code;
int ret;

if (!remote_pad)
return -ENOTCONN;

sd = media_entity_to_v4l2_subdev(remote_pad->entity);
r_stream = ipu7_isys_get_src_stream_by_src_pad(sd, remote_pad->index);

ret = ipu7_isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream,
&format);
Expand Down Expand Up @@ -761,17 +760,7 @@ static int reset_start_streaming(struct ipu7_isys_video *av)
goto out;

bl = &__bl;
int retry = 5;
while (retry--) {
ret = buffer_list_get(stream, bl);
if (ret < 0) {
dev_dbg(dev, "wait for incoming buffer, retry %d\n", retry);
usleep_range(100000, 110000);
continue;
}
break;
}

ret = buffer_list_get(stream, bl);
/*
* In reset start streaming and no buffer available,
* it is considered that gstreamer has been closed,
Expand Down
35 changes: 10 additions & 25 deletions drivers/media/pci/intel/ipu7/ipu7-isys-subdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,22 @@ static int subdev_set_routing(struct v4l2_subdev *sd,
.code = MEDIA_BUS_FMT_SGRBG10_1X10,
.field = V4L2_FIELD_NONE,
};
struct v4l2_subdev_route *route;
int ret;

ret = v4l2_subdev_routing_validate(sd, routing,
V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 |
V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING);
if (ret)
return ret;

/*
* The device doesn't support source multiplexing, set all source
* streams to 0 to simplify stream handling through the driver.
*/
for_each_active_route(routing, route)
route->source_stream = 0;

return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &fmt);
}

Expand All @@ -222,30 +231,6 @@ int ipu7_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream,
return fmt ? 0 : -EINVAL;
}

u32 ipu7_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad)
{
struct v4l2_subdev_state *state;
struct v4l2_subdev_route *routes;
u32 source_stream = 0;
unsigned int i;

state = v4l2_subdev_lock_and_get_active_state(sd);
if (!state)
return 0;

routes = state->routing.routes;
for (i = 0; i < state->routing.num_routes; i++) {
if (routes[i].source_pad == pad) {
source_stream = routes[i].source_stream;
break;
}
}

v4l2_subdev_unlock_state(state);

return source_stream;
}

static int ipu7_isys_subdev_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
Expand Down
1 change: 0 additions & 1 deletion drivers/media/pci/intel/ipu7/ipu7-isys-subdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ int ipu7_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum
*code);
u32 ipu7_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad);
int ipu7_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream,
struct v4l2_mbus_framefmt *format);
int ipu7_isys_subdev_set_routing(struct v4l2_subdev *sd,
Expand Down
Loading