mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
media: vsp1: Add VSPX support
Add support for VSPX, a specialized version of the VSP2 that transfers data to the ISP. The VSPX is composed of two RPF units to read data from external memory and an IIF instance that performs transfer towards the ISP. The VSPX is supported through a newly introduced vsp1_vspx.c file that exposes two interfaces: vsp1_vspx interface, declared in vsp1_vspx.h for the vsp1 core to initialize and cleanup the VSPX, and a vsp1_isp interface, declared in include/media/vsp1.h for the ISP driver to control the VSPX operations. Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com> Link: https://lore.kernel.org/r/20250617-b4-vspx-v13-1-9f4054c1c9af@ideasonboard.com Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
committed by
Hans Verkuil
parent
fe2a3493c5
commit
d06c1a9f34
@@ -6,5 +6,6 @@ vsp1-y += vsp1_clu.o vsp1_hsit.o vsp1_lut.o
|
||||
vsp1-y += vsp1_brx.o vsp1_sru.o vsp1_uds.o
|
||||
vsp1-y += vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
|
||||
vsp1-y += vsp1_iif.o vsp1_lif.o vsp1_uif.o
|
||||
vsp1-y += vsp1_vspx.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
|
||||
|
||||
@@ -111,6 +111,7 @@ struct vsp1_device {
|
||||
struct media_entity_operations media_ops;
|
||||
|
||||
struct vsp1_drm *drm;
|
||||
struct vsp1_vspx *vspx;
|
||||
};
|
||||
|
||||
int vsp1_device_get(struct vsp1_device *vsp1);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "vsp1_uds.h"
|
||||
#include "vsp1_uif.h"
|
||||
#include "vsp1_video.h"
|
||||
#include "vsp1_vspx.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Interrupt Handling
|
||||
@@ -491,7 +492,10 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
|
||||
|
||||
ret = media_device_register(mdev);
|
||||
} else {
|
||||
ret = vsp1_drm_init(vsp1);
|
||||
if (vsp1->info->version == VI6_IP_VERSION_MODEL_VSPX_GEN4)
|
||||
ret = vsp1_vspx_init(vsp1);
|
||||
else
|
||||
ret = vsp1_drm_init(vsp1);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -858,6 +862,13 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
|
||||
.uif_count = 2,
|
||||
.wpf_count = 1,
|
||||
.num_bru_inputs = 5,
|
||||
}, {
|
||||
.version = VI6_IP_VERSION_MODEL_VSPX_GEN4,
|
||||
.model = "VSP2-X",
|
||||
.gen = 4,
|
||||
.features = VSP1_HAS_IIF,
|
||||
.rpf_count = 2,
|
||||
.wpf_count = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -799,6 +799,7 @@
|
||||
#define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
|
||||
#define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)
|
||||
#define VI6_IP_VERSION_MODEL_VSPD_GEN4 (0x1c << 8)
|
||||
#define VI6_IP_VERSION_MODEL_VSPX_GEN4 (0x1d << 8)
|
||||
/* RZ/G2L SoCs have no version register, So use 0x80 as the model version */
|
||||
#define VI6_IP_VERSION_MODEL_VSPD_RZG2L (0x80 << 8)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* vsp1_vspx.h -- R-Car Gen 4 VSPX
|
||||
*
|
||||
* Copyright (C) 2025 Ideas On Board Oy
|
||||
* Copyright (C) 2025 Renesas Electronics Corporation
|
||||
*/
|
||||
#ifndef __VSP1_VSPX_H__
|
||||
#define __VSP1_VSPX_H__
|
||||
|
||||
#include "vsp1.h"
|
||||
|
||||
int vsp1_vspx_init(struct vsp1_device *vsp1);
|
||||
void vsp1_vspx_cleanup(struct vsp1_device *vsp1);
|
||||
|
||||
#endif /* __VSP1_VSPX_H__ */
|
||||
@@ -14,6 +14,11 @@
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
struct device;
|
||||
struct vsp1_dl_list;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* VSP1 DU interface
|
||||
*/
|
||||
|
||||
int vsp1_du_init(struct device *dev);
|
||||
|
||||
@@ -121,4 +126,88 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
|
||||
int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
|
||||
void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* VSP1 ISP interface
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct vsp1_isp_buffer_desc - Describe a buffer allocated by VSPX
|
||||
* @size: Byte size of the buffer allocated by VSPX
|
||||
* @cpu_addr: CPU-mapped address of a buffer allocated by VSPX
|
||||
* @dma_addr: bus address of a buffer allocated by VSPX
|
||||
*/
|
||||
struct vsp1_isp_buffer_desc {
|
||||
size_t size;
|
||||
void *cpu_addr;
|
||||
dma_addr_t dma_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vsp1_isp_job_desc - Describe a VSPX buffer transfer request
|
||||
* @config: ConfigDMA buffer descriptor
|
||||
* @config.pairs: number of reg-value pairs in the ConfigDMA buffer
|
||||
* @config.mem: bus address of the ConfigDMA buffer
|
||||
* @img: RAW image buffer descriptor
|
||||
* @img.fmt: RAW image format
|
||||
* @img.mem: bus address of the RAW image buffer
|
||||
* @dl: pointer to the display list populated by the VSPX driver in the
|
||||
* vsp1_isp_job_prepare() function
|
||||
*
|
||||
* Describe a transfer request for the VSPX to perform on behalf of the ISP.
|
||||
* The job descriptor contains an optional ConfigDMA buffer and one RAW image
|
||||
* buffer. Set config.pairs to 0 if no ConfigDMA buffer should be transferred.
|
||||
* The minimum number of config.pairs that can be written using ConfigDMA is 17.
|
||||
* A number of pairs < 16 corrupts the output image. A number of pairs == 16
|
||||
* freezes the VSPX operation. If the ISP driver has to write less than 17 pairs
|
||||
* it shall pad the buffer with writes directed to registers that have no effect
|
||||
* or avoid using ConfigDMA at all for such small write sequences.
|
||||
*
|
||||
* The ISP driver shall pass an instance this type to the vsp1_isp_job_prepare()
|
||||
* function that will populate the display list pointer @dl using the @config
|
||||
* and @img descriptors. When the job has to be run on the VSPX, the descriptor
|
||||
* shall be passed to vsp1_isp_job_run() which consumes the display list.
|
||||
*
|
||||
* Job descriptors not yet run shall be released with a call to
|
||||
* vsp1_isp_job_release() when stopping the streaming in order to properly
|
||||
* release the resources acquired by vsp1_isp_job_prepare().
|
||||
*/
|
||||
struct vsp1_isp_job_desc {
|
||||
struct {
|
||||
unsigned int pairs;
|
||||
dma_addr_t mem;
|
||||
} config;
|
||||
struct {
|
||||
struct v4l2_pix_format_mplane fmt;
|
||||
dma_addr_t mem;
|
||||
} img;
|
||||
struct vsp1_dl_list *dl;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vsp1_vspx_frame_end - VSPX frame end callback data
|
||||
* @vspx_frame_end: Frame end callback. Called after a transfer job has been
|
||||
* completed. If the job includes both a ConfigDMA and a
|
||||
* RAW image, the callback is called after both have been
|
||||
* transferred
|
||||
* @frame_end_data: Frame end callback data, passed to vspx_frame_end
|
||||
*/
|
||||
struct vsp1_vspx_frame_end {
|
||||
void (*vspx_frame_end)(void *data);
|
||||
void *frame_end_data;
|
||||
};
|
||||
|
||||
int vsp1_isp_init(struct device *dev);
|
||||
struct device *vsp1_isp_get_bus_master(struct device *dev);
|
||||
int vsp1_isp_alloc_buffer(struct device *dev, size_t size,
|
||||
struct vsp1_isp_buffer_desc *buffer_desc);
|
||||
void vsp1_isp_free_buffer(struct device *dev,
|
||||
struct vsp1_isp_buffer_desc *buffer_desc);
|
||||
int vsp1_isp_start_streaming(struct device *dev,
|
||||
struct vsp1_vspx_frame_end *frame_end);
|
||||
void vsp1_isp_stop_streaming(struct device *dev);
|
||||
int vsp1_isp_job_prepare(struct device *dev,
|
||||
struct vsp1_isp_job_desc *job);
|
||||
int vsp1_isp_job_run(struct device *dev, struct vsp1_isp_job_desc *job);
|
||||
void vsp1_isp_job_release(struct device *dev, struct vsp1_isp_job_desc *job);
|
||||
|
||||
#endif /* __MEDIA_VSP1_H__ */
|
||||
|
||||
Reference in New Issue
Block a user