rkisp1: Add i.MX8MP support
-----BEGIN PGP SIGNATURE----- iJgEABYKAEAWIQTAnvhxs4J7QT+XHKnMPy2AAyfeZAUCZdiOeyIcbGF1cmVudC5w aW5jaGFydEBpZGVhc29uYm9hcmQuY29tAAoJEMw/LYADJ95kLSEBAPKGOtKxuEwK CVpWvxStpfm0Xs3aAdSG6UO99b81rrwtAQCVOv71Dh/c7JRnbEHeOK5OaOgDJLEf MAMQLBJno+EkAA== =gshp -----END PGP SIGNATURE----- Merge tag 'tags/media-next-rkisp1-20240223' of git://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux.git into media_stage This adds i.MX8MP support to the rkisp1 driver. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Link: https://patchwork.linuxtv.org/project/linux-media/patch/20240223123556.GA26004@pendragon.ideasonboard.com/
This commit is contained in:
commit
cecce089b9
@ -16,6 +16,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8mp-isp
|
||||
- rockchip,px30-cif-isp
|
||||
- rockchip,rk3399-cif-isp
|
||||
|
||||
@ -36,9 +37,9 @@ properties:
|
||||
minItems: 3
|
||||
items:
|
||||
# isp0 and isp1
|
||||
- description: ISP clock
|
||||
- description: ISP AXI clock
|
||||
- description: ISP AHB clock
|
||||
- description: ISP clock (for imx8mp, clk)
|
||||
- description: ISP AXI clock (for imx8mp, m_hclk)
|
||||
- description: ISP AHB clock (for imx8mp, hclk)
|
||||
# only for isp1
|
||||
- description: ISP Pixel clock
|
||||
|
||||
@ -52,6 +53,13 @@ properties:
|
||||
# only for isp1
|
||||
- const: pclk
|
||||
|
||||
fsl,blk-ctrl:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
maxItems: 1
|
||||
description:
|
||||
A phandle to the media block control for the ISP, followed by a cell
|
||||
containing the index of the gasket.
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
@ -113,9 +121,6 @@ required:
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- iommus
|
||||
- phys
|
||||
- phy-names
|
||||
- power-domains
|
||||
- ports
|
||||
|
||||
@ -143,6 +148,26 @@ allOf:
|
||||
required:
|
||||
- interrupt-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8mp-isp
|
||||
then:
|
||||
properties:
|
||||
iommus: false
|
||||
phys: false
|
||||
phy-names: false
|
||||
required:
|
||||
- fsl,blk-ctrl
|
||||
else:
|
||||
properties:
|
||||
fsl,blk-ctrl: false
|
||||
required:
|
||||
- iommus
|
||||
- phys
|
||||
- phy-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -47,13 +47,18 @@ enum rkisp1_plane {
|
||||
* @fourcc: pixel format
|
||||
* @fmt_type: helper filed for pixel format
|
||||
* @uv_swap: if cb cr swapped, for yuv
|
||||
* @yc_swap: if y and cb/cr swapped, for yuv
|
||||
* @byte_swap: if byte pairs are swapped, for raw
|
||||
* @write_format: defines how YCbCr self picture data is written to memory
|
||||
* @output_format: defines sp output format
|
||||
* @output_format: defines the output format (RKISP1_CIF_MI_INIT_MP_OUTPUT_* for
|
||||
* the main path and RKISP1_MI_CTRL_SP_OUTPUT_* for the self path)
|
||||
* @mbus: the mbus code on the src resizer pad that matches the pixel format
|
||||
*/
|
||||
struct rkisp1_capture_fmt_cfg {
|
||||
u32 fourcc;
|
||||
u8 uv_swap;
|
||||
u32 uv_swap : 1;
|
||||
u32 yc_swap : 1;
|
||||
u32 byte_swap : 1;
|
||||
u32 write_format;
|
||||
u32 output_format;
|
||||
u32 mbus;
|
||||
@ -94,36 +99,50 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
|
||||
.fourcc = V4L2_PIX_FMT_YUYV,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_UYVY,
|
||||
.uv_swap = 0,
|
||||
.yc_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_YUV422P,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV16,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV61,
|
||||
.uv_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV16M,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV61M,
|
||||
.uv_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_YVU422M,
|
||||
.uv_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
},
|
||||
/* yuv400 */
|
||||
@ -131,6 +150,7 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
|
||||
.fourcc = V4L2_PIX_FMT_GREY,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
},
|
||||
/* yuv420 */
|
||||
@ -138,81 +158,107 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
|
||||
.fourcc = V4L2_PIX_FMT_NV21,
|
||||
.uv_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV12,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV21M,
|
||||
.uv_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_NV12M,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_YUV420,
|
||||
.uv_swap = 0,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_YVU420,
|
||||
.uv_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
|
||||
},
|
||||
/* raw */
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB8,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
|
||||
.mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGRBG8,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
|
||||
.mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGBRG8,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
|
||||
.mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SBGGR8,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
|
||||
.mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB10,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
|
||||
.mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGRBG10,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
|
||||
.mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGBRG10,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
|
||||
.mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SBGGR10,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
|
||||
.mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SRGGB12,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
|
||||
.mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGRBG12,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
|
||||
.mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SGBRG12,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
|
||||
.mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_SBGGR12,
|
||||
.byte_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
|
||||
.output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
|
||||
.mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
|
||||
},
|
||||
};
|
||||
@ -229,6 +275,13 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
|
||||
.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
|
||||
.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_UYVY,
|
||||
.uv_swap = 0,
|
||||
.yc_swap = 1,
|
||||
.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
|
||||
.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
|
||||
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_YUV422P,
|
||||
.uv_swap = 0,
|
||||
@ -442,6 +495,14 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
|
||||
rkisp1_write(rkisp1, cap->config->mi.cr_size_init,
|
||||
rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
|
||||
|
||||
if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_LLENGTH, cap->stride);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_WIDTH, pixm->width);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_HEIGHT, pixm->height);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_SIZE,
|
||||
cap->stride * pixm->height);
|
||||
}
|
||||
|
||||
rkisp1_irq_frame_end_enable(cap);
|
||||
|
||||
/* set uv swapping for semiplanar formats */
|
||||
@ -454,6 +515,25 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* U/V swapping with the MI_XTD_FORMAT_CTRL register only works for
|
||||
* NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
|
||||
* YVYU and VYUY cannot be supported with this method.
|
||||
*/
|
||||
if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
|
||||
reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
|
||||
if (cap->pix.cfg->yc_swap || cap->pix.cfg->byte_swap)
|
||||
reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
|
||||
else
|
||||
reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
|
||||
|
||||
reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT;
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
|
||||
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
|
||||
cap->pix.cfg->output_format);
|
||||
}
|
||||
|
||||
rkisp1_mi_config_ctrl(cap);
|
||||
|
||||
reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
|
||||
@ -479,11 +559,11 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
|
||||
rkisp1_write(rkisp1, cap->config->mi.cr_size_init,
|
||||
rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
|
||||
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_LLENGTH, cap->sp_y_stride);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_LLENGTH, cap->stride);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_WIDTH, pixm->width);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT, pixm->height);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_SIZE,
|
||||
cap->sp_y_stride * pixm->height);
|
||||
cap->stride * pixm->height);
|
||||
|
||||
rkisp1_irq_frame_end_enable(cap);
|
||||
|
||||
@ -497,6 +577,20 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* U/V swapping with the MI_XTD_FORMAT_CTRL register only works for
|
||||
* NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
|
||||
* YVYU and VYUY cannot be supported with this method.
|
||||
*/
|
||||
if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
|
||||
reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
|
||||
if (cap->pix.cfg->yc_swap)
|
||||
reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES;
|
||||
else
|
||||
reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES;
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
|
||||
}
|
||||
|
||||
rkisp1_mi_config_ctrl(cap);
|
||||
|
||||
mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
|
||||
@ -640,11 +734,13 @@ static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
|
||||
|
||||
static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
|
||||
{
|
||||
u8 shift = rkisp1_has_feature(cap->rkisp1, DMA_34BIT) ? 2 : 0;
|
||||
|
||||
cap->buf.curr = cap->buf.next;
|
||||
cap->buf.next = NULL;
|
||||
|
||||
if (!list_empty(&cap->buf.queue)) {
|
||||
u32 *buff_addr;
|
||||
dma_addr_t *buff_addr;
|
||||
|
||||
cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
|
||||
list_del(&cap->buf.next->queue);
|
||||
@ -652,7 +748,7 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
|
||||
buff_addr = cap->buf.next->buff_addr;
|
||||
|
||||
rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
|
||||
buff_addr[RKISP1_PLANE_Y]);
|
||||
buff_addr[RKISP1_PLANE_Y] >> shift);
|
||||
/*
|
||||
* In order to support grey format we capture
|
||||
* YUV422 planar format from the camera and
|
||||
@ -661,17 +757,17 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
|
||||
if (cap->pix.cfg->fourcc == V4L2_PIX_FMT_GREY) {
|
||||
rkisp1_write(cap->rkisp1,
|
||||
cap->config->mi.cb_base_ad_init,
|
||||
cap->buf.dummy.dma_addr);
|
||||
cap->buf.dummy.dma_addr >> shift);
|
||||
rkisp1_write(cap->rkisp1,
|
||||
cap->config->mi.cr_base_ad_init,
|
||||
cap->buf.dummy.dma_addr);
|
||||
cap->buf.dummy.dma_addr >> shift);
|
||||
} else {
|
||||
rkisp1_write(cap->rkisp1,
|
||||
cap->config->mi.cb_base_ad_init,
|
||||
buff_addr[RKISP1_PLANE_CB]);
|
||||
buff_addr[RKISP1_PLANE_CB] >> shift);
|
||||
rkisp1_write(cap->rkisp1,
|
||||
cap->config->mi.cr_base_ad_init,
|
||||
buff_addr[RKISP1_PLANE_CR]);
|
||||
buff_addr[RKISP1_PLANE_CR] >> shift);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -679,11 +775,11 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
|
||||
* throw data if there is no available buffer.
|
||||
*/
|
||||
rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
|
||||
cap->buf.dummy.dma_addr);
|
||||
cap->buf.dummy.dma_addr >> shift);
|
||||
rkisp1_write(cap->rkisp1, cap->config->mi.cb_base_ad_init,
|
||||
cap->buf.dummy.dma_addr);
|
||||
cap->buf.dummy.dma_addr >> shift);
|
||||
rkisp1_write(cap->rkisp1, cap->config->mi.cr_base_ad_init,
|
||||
cap->buf.dummy.dma_addr);
|
||||
cap->buf.dummy.dma_addr >> shift);
|
||||
}
|
||||
|
||||
/* Set plane offsets */
|
||||
@ -722,6 +818,7 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
|
||||
{
|
||||
struct device *dev = ctx;
|
||||
struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
|
||||
unsigned int dev_count = rkisp1_path_count(rkisp1);
|
||||
unsigned int i;
|
||||
u32 status;
|
||||
|
||||
@ -731,7 +828,7 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
|
||||
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, status);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
|
||||
for (i = 0; i < dev_count; ++i) {
|
||||
struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
|
||||
|
||||
if (!(status & RKISP1_CIF_MI_FRAME(cap)))
|
||||
@ -888,6 +985,7 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
|
||||
{
|
||||
struct rkisp1_device *rkisp1 = cap->rkisp1;
|
||||
struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
|
||||
bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
|
||||
|
||||
cap->ops->set_data_path(cap);
|
||||
cap->ops->config(cap);
|
||||
@ -896,19 +994,40 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
|
||||
spin_lock_irq(&cap->buf.lock);
|
||||
rkisp1_set_next_buf(cap);
|
||||
cap->ops->enable(cap);
|
||||
/* It's safe to configure ACTIVE and SHADOW registers for the
|
||||
* first stream. While when the second is starting, do NOT
|
||||
* force update because it also updates the first one.
|
||||
|
||||
/*
|
||||
* It's safe to configure ACTIVE and SHADOW registers for the first
|
||||
* stream. While when the second is starting, do NOT force update
|
||||
* because it also updates the first one.
|
||||
*
|
||||
* The latter case would drop one more buffer(that is 2) since
|
||||
* there's no buffer in a shadow register when the second FE received.
|
||||
* This's also required because the second FE maybe corrupt
|
||||
* especially when run at 120fps.
|
||||
* The latter case would drop one more buffer(that is 2) since there's
|
||||
* no buffer in a shadow register when the second FE received. This's
|
||||
* also required because the second FE maybe corrupt especially when
|
||||
* run at 120fps.
|
||||
*/
|
||||
if (!other->is_streaming) {
|
||||
/* force cfg update */
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
|
||||
RKISP1_CIF_MI_INIT_SOFT_UPD);
|
||||
if (!has_self_path || !other->is_streaming) {
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Force cfg update.
|
||||
*
|
||||
* The ISP8000 (implementing the MAIN_STRIDE feature) as a
|
||||
* mp_output_format field in the CIF_MI_INIT register that must
|
||||
* be preserved. It can be read back, but it is not clear what
|
||||
* other register bits will return. Mask them out.
|
||||
*
|
||||
* On Rockchip platforms, the CIF_MI_INIT register is marked as
|
||||
* write-only and reads as zeros. We can skip reading it.
|
||||
*/
|
||||
if (rkisp1_has_feature(rkisp1, MAIN_STRIDE))
|
||||
reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_INIT)
|
||||
& RKISP1_CIF_MI_INIT_MP_OUTPUT_MASK;
|
||||
else
|
||||
reg = 0;
|
||||
|
||||
reg |= RKISP1_CIF_MI_INIT_SOFT_UPD;
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT, reg);
|
||||
|
||||
rkisp1_set_next_buf(cap);
|
||||
}
|
||||
spin_unlock_irq(&cap->buf.lock);
|
||||
@ -1092,8 +1211,8 @@ static const struct vb2_ops rkisp1_vb2_ops = {
|
||||
*/
|
||||
|
||||
static const struct v4l2_format_info *
|
||||
rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
|
||||
enum rkisp1_stream_id id)
|
||||
rkisp1_fill_pixfmt(const struct rkisp1_capture *cap,
|
||||
struct v4l2_pix_format_mplane *pixm)
|
||||
{
|
||||
struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
|
||||
const struct v4l2_format_info *info;
|
||||
@ -1106,10 +1225,13 @@ rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
|
||||
|
||||
/*
|
||||
* The SP supports custom strides, expressed as a number of pixels for
|
||||
* the Y plane. Clamp the stride to a reasonable value to avoid integer
|
||||
* overflows when calculating the bytesperline and sizeimage values.
|
||||
* the Y plane, and so does the MP in ISP versions that have the
|
||||
* MAIN_STRIDE feature. Clamp the stride to a reasonable value to avoid
|
||||
* integer overflows when calculating the bytesperline and sizeimage
|
||||
* values.
|
||||
*/
|
||||
if (id == RKISP1_SELFPATH)
|
||||
if (cap->id == RKISP1_SELFPATH ||
|
||||
rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE))
|
||||
stride = clamp(DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]),
|
||||
pixm->width, 65536U);
|
||||
else
|
||||
@ -1144,10 +1266,14 @@ rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
|
||||
static const struct rkisp1_capture_fmt_cfg *
|
||||
rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
|
||||
{
|
||||
bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < cap->config->fmt_size; i++) {
|
||||
if (cap->config->fmts[i].fourcc == pixelfmt)
|
||||
const struct rkisp1_capture_fmt_cfg *fmt = &cap->config->fmts[i];
|
||||
|
||||
if (fmt->fourcc == pixelfmt &&
|
||||
(!fmt->yc_swap || yc_swap_support))
|
||||
return &cap->config->fmts[i];
|
||||
}
|
||||
return NULL;
|
||||
@ -1184,7 +1310,7 @@ static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
|
||||
pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
|
||||
pixm->quantization = V4L2_QUANTIZATION_DEFAULT;
|
||||
|
||||
info = rkisp1_fill_pixfmt(pixm, cap->id);
|
||||
info = rkisp1_fill_pixfmt(cap, pixm);
|
||||
|
||||
if (fmt_cfg)
|
||||
*fmt_cfg = fmt;
|
||||
@ -1196,12 +1322,9 @@ static void rkisp1_set_fmt(struct rkisp1_capture *cap,
|
||||
struct v4l2_pix_format_mplane *pixm)
|
||||
{
|
||||
rkisp1_try_fmt(cap, pixm, &cap->pix.cfg, &cap->pix.info);
|
||||
cap->pix.fmt = *pixm;
|
||||
|
||||
/* SP supports custom stride in number of pixels of the Y plane */
|
||||
if (cap->id == RKISP1_SELFPATH)
|
||||
cap->sp_y_stride = pixm->plane_fmt[0].bytesperline /
|
||||
cap->pix.info->bpp[0];
|
||||
cap->pix.fmt = *pixm;
|
||||
cap->stride = pixm->plane_fmt[0].bytesperline / cap->pix.info->bpp[0];
|
||||
}
|
||||
|
||||
static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
|
||||
@ -1219,23 +1342,29 @@ static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
|
||||
{
|
||||
struct rkisp1_capture *cap = video_drvdata(file);
|
||||
const struct rkisp1_capture_fmt_cfg *fmt = NULL;
|
||||
bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE);
|
||||
unsigned int i, n = 0;
|
||||
|
||||
if (!f->mbus_code) {
|
||||
if (f->index >= cap->config->fmt_size)
|
||||
return -EINVAL;
|
||||
if (f->index >= cap->config->fmt_size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!f->mbus_code && yc_swap_support) {
|
||||
fmt = &cap->config->fmts[f->index];
|
||||
f->pixelformat = fmt->fourcc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < cap->config->fmt_size; i++) {
|
||||
if (cap->config->fmts[i].mbus != f->mbus_code)
|
||||
fmt = &cap->config->fmts[i];
|
||||
|
||||
if (f->mbus_code && fmt->mbus != f->mbus_code)
|
||||
continue;
|
||||
|
||||
if (!yc_swap_support && fmt->yc_swap)
|
||||
continue;
|
||||
|
||||
if (n++ == f->index) {
|
||||
f->pixelformat = cap->config->fmts[i].fourcc;
|
||||
f->pixelformat = fmt->fourcc;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1498,10 +1627,11 @@ rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
|
||||
|
||||
int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
|
||||
{
|
||||
unsigned int dev_count = rkisp1_path_count(rkisp1);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
|
||||
for (i = 0; i < dev_count; i++) {
|
||||
struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
|
||||
|
||||
rkisp1_capture_init(rkisp1, i);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "rkisp1-regs.h"
|
||||
|
||||
struct dentry;
|
||||
struct regmap;
|
||||
|
||||
/*
|
||||
* flags on the 'direction' field in struct rkisp1_mbus_info' that indicate
|
||||
@ -110,6 +111,10 @@ enum rkisp1_isp_pad {
|
||||
* enum rkisp1_feature - ISP features
|
||||
*
|
||||
* @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
|
||||
* @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
|
||||
* @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
|
||||
* @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
|
||||
* @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses
|
||||
*
|
||||
* The ISP features are stored in a bitmask in &rkisp1_info.features and allow
|
||||
* the driver to implement support for features present in some ISP versions
|
||||
@ -117,8 +122,15 @@ enum rkisp1_isp_pad {
|
||||
*/
|
||||
enum rkisp1_feature {
|
||||
RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
|
||||
RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
|
||||
RKISP1_FEATURE_SELF_PATH = BIT(2),
|
||||
RKISP1_FEATURE_DUAL_CROP = BIT(3),
|
||||
RKISP1_FEATURE_DMA_34BIT = BIT(4),
|
||||
};
|
||||
|
||||
#define rkisp1_has_feature(rkisp1, feature) \
|
||||
((rkisp1)->info->features & RKISP1_FEATURE_##feature)
|
||||
|
||||
/*
|
||||
* struct rkisp1_info - Model-specific ISP Information
|
||||
*
|
||||
@ -229,7 +241,7 @@ struct rkisp1_vdev_node {
|
||||
struct rkisp1_buffer {
|
||||
struct vb2_v4l2_buffer vb;
|
||||
struct list_head queue;
|
||||
u32 buff_addr[VIDEO_MAX_PLANES];
|
||||
dma_addr_t buff_addr[VIDEO_MAX_PLANES];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -263,7 +275,7 @@ struct rkisp1_device;
|
||||
* handler to stop the streaming by waiting on the 'done' wait queue.
|
||||
* If the irq handler is not called, the stream is stopped by the callback
|
||||
* after timeout.
|
||||
* @sp_y_stride: the selfpath allows to configure a y stride that is longer than the image width.
|
||||
* @stride: the line stride for the first plane, in pixel units
|
||||
* @buf.lock: lock to protect buf.queue
|
||||
* @buf.queue: queued buffer list
|
||||
* @buf.dummy: dummy space to store dropped data
|
||||
@ -284,7 +296,7 @@ struct rkisp1_capture {
|
||||
bool is_streaming;
|
||||
bool is_stopping;
|
||||
wait_queue_head_t done;
|
||||
unsigned int sp_y_stride;
|
||||
unsigned int stride;
|
||||
struct {
|
||||
/* protects queue, curr and next */
|
||||
spinlock_t lock;
|
||||
@ -435,6 +447,8 @@ struct rkisp1_debug {
|
||||
* @dev: a pointer to the struct device
|
||||
* @clk_size: number of clocks
|
||||
* @clks: array of clocks
|
||||
* @gasket: the gasket - i.MX8MP only
|
||||
* @gasket_id: the gasket ID (0 or 1) - i.MX8MP only
|
||||
* @v4l2_dev: v4l2_device variable
|
||||
* @media_dev: media_device variable
|
||||
* @notifier: a notifier to register on the v4l2-async API to be notified on the sensor
|
||||
@ -456,6 +470,8 @@ struct rkisp1_device {
|
||||
struct device *dev;
|
||||
unsigned int clk_size;
|
||||
struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
|
||||
struct regmap *gasket;
|
||||
unsigned int gasket_id;
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct media_device media_dev;
|
||||
struct v4l2_async_notifier notifier;
|
||||
@ -524,6 +540,19 @@ int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
|
||||
*/
|
||||
const struct rkisp1_mbus_info *rkisp1_mbus_info_get_by_index(unsigned int index);
|
||||
|
||||
/*
|
||||
* rkisp1_path_count - Return the number of paths supported by the device
|
||||
*
|
||||
* Some devices only have a main path, while other device have both a main path
|
||||
* and a self path. This function returns the number of paths that this device
|
||||
* has, based on the feature flags. It should be used insted of checking
|
||||
* ARRAY_SIZE of capture_devs/resizer_devs.
|
||||
*/
|
||||
static inline unsigned int rkisp1_path_count(struct rkisp1_device *rkisp1)
|
||||
{
|
||||
return rkisp1_has_feature(rkisp1, SELF_PATH) ? 2 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
|
||||
*
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_graph.h>
|
||||
@ -207,7 +208,7 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
|
||||
switch (reg) {
|
||||
case 0:
|
||||
/* MIPI CSI-2 port */
|
||||
if (!(rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)) {
|
||||
if (!rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
|
||||
dev_err(rkisp1->dev,
|
||||
"internal CSI must be available for port 0\n");
|
||||
ret = -EINVAL;
|
||||
@ -336,10 +337,11 @@ static const struct dev_pm_ops rkisp1_pm_ops = {
|
||||
|
||||
static int rkisp1_create_links(struct rkisp1_device *rkisp1)
|
||||
{
|
||||
unsigned int dev_count = rkisp1_path_count(rkisp1);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
|
||||
if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
|
||||
/* Link the CSI receiver to the ISP. */
|
||||
ret = media_create_pad_link(&rkisp1->csi.sd.entity,
|
||||
RKISP1_CSI_PAD_SRC,
|
||||
@ -351,7 +353,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
|
||||
}
|
||||
|
||||
/* create ISP->RSZ->CAP links */
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < dev_count; i++) {
|
||||
struct media_entity *resizer =
|
||||
&rkisp1->resizer_devs[i].sd.entity;
|
||||
struct media_entity *capture =
|
||||
@ -391,7 +393,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
|
||||
|
||||
static void rkisp1_entities_unregister(struct rkisp1_device *rkisp1)
|
||||
{
|
||||
if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
|
||||
if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
|
||||
rkisp1_csi_unregister(rkisp1);
|
||||
rkisp1_params_unregister(rkisp1);
|
||||
rkisp1_stats_unregister(rkisp1);
|
||||
@ -424,7 +426,7 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
|
||||
if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
|
||||
ret = rkisp1_csi_register(rkisp1);
|
||||
if (ret)
|
||||
goto error;
|
||||
@ -483,7 +485,9 @@ static const struct rkisp1_info px30_isp_info = {
|
||||
.isrs = px30_isp_isrs,
|
||||
.isr_size = ARRAY_SIZE(px30_isp_isrs),
|
||||
.isp_ver = RKISP1_V12,
|
||||
.features = RKISP1_FEATURE_MIPI_CSI2,
|
||||
.features = RKISP1_FEATURE_MIPI_CSI2
|
||||
| RKISP1_FEATURE_SELF_PATH
|
||||
| RKISP1_FEATURE_DUAL_CROP,
|
||||
};
|
||||
|
||||
static const char * const rk3399_isp_clks[] = {
|
||||
@ -502,7 +506,29 @@ static const struct rkisp1_info rk3399_isp_info = {
|
||||
.isrs = rk3399_isp_isrs,
|
||||
.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
|
||||
.isp_ver = RKISP1_V10,
|
||||
.features = RKISP1_FEATURE_MIPI_CSI2,
|
||||
.features = RKISP1_FEATURE_MIPI_CSI2
|
||||
| RKISP1_FEATURE_SELF_PATH
|
||||
| RKISP1_FEATURE_DUAL_CROP,
|
||||
};
|
||||
|
||||
static const char * const imx8mp_isp_clks[] = {
|
||||
"isp",
|
||||
"hclk",
|
||||
"aclk",
|
||||
};
|
||||
|
||||
static const struct rkisp1_isr_data imx8mp_isp_isrs[] = {
|
||||
{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) },
|
||||
};
|
||||
|
||||
static const struct rkisp1_info imx8mp_isp_info = {
|
||||
.clks = imx8mp_isp_clks,
|
||||
.clk_size = ARRAY_SIZE(imx8mp_isp_clks),
|
||||
.isrs = imx8mp_isp_isrs,
|
||||
.isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
|
||||
.isp_ver = RKISP1_V_IMX8MP,
|
||||
.features = RKISP1_FEATURE_MAIN_STRIDE
|
||||
| RKISP1_FEATURE_DMA_34BIT,
|
||||
};
|
||||
|
||||
static const struct of_device_id rkisp1_of_match[] = {
|
||||
@ -514,6 +540,10 @@ static const struct of_device_id rkisp1_of_match[] = {
|
||||
.compatible = "rockchip,rk3399-cif-isp",
|
||||
.data = &rk3399_isp_info,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,imx8mp-isp",
|
||||
.data = &imx8mp_isp_info,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rkisp1_of_match);
|
||||
@ -525,6 +555,7 @@ static int rkisp1_probe(struct platform_device *pdev)
|
||||
struct rkisp1_device *rkisp1;
|
||||
struct v4l2_device *v4l2_dev;
|
||||
unsigned int i;
|
||||
u64 dma_mask;
|
||||
int ret, irq;
|
||||
u32 cif_id;
|
||||
|
||||
@ -538,6 +569,13 @@ static int rkisp1_probe(struct platform_device *pdev)
|
||||
dev_set_drvdata(dev, rkisp1);
|
||||
rkisp1->dev = dev;
|
||||
|
||||
dma_mask = rkisp1_has_feature(rkisp1, DMA_34BIT) ? DMA_BIT_MASK(34) :
|
||||
DMA_BIT_MASK(32);
|
||||
|
||||
ret = dma_set_mask_and_coherent(dev, dma_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_init(&rkisp1->stream_lock);
|
||||
|
||||
rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
|
||||
@ -574,6 +612,21 @@ static int rkisp1_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
rkisp1->clk_size = info->clk_size;
|
||||
|
||||
if (info->isp_ver == RKISP1_V_IMX8MP) {
|
||||
unsigned int id;
|
||||
|
||||
rkisp1->gasket = syscon_regmap_lookup_by_phandle_args(dev->of_node,
|
||||
"fsl,blk-ctrl",
|
||||
1, &id);
|
||||
if (IS_ERR(rkisp1->gasket)) {
|
||||
ret = PTR_ERR(rkisp1->gasket);
|
||||
dev_err(dev, "failed to get gasket: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rkisp1->gasket_id = id;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||
@ -628,7 +681,7 @@ static int rkisp1_probe(struct platform_device *pdev)
|
||||
err_unreg_entities:
|
||||
rkisp1_entities_unregister(rkisp1);
|
||||
err_cleanup_csi:
|
||||
if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
|
||||
if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
|
||||
rkisp1_csi_cleanup(rkisp1);
|
||||
err_unreg_media_dev:
|
||||
media_device_unregister(&rkisp1->media_dev);
|
||||
@ -649,7 +702,7 @@ static void rkisp1_remove(struct platform_device *pdev)
|
||||
v4l2_async_nf_cleanup(&rkisp1->notifier);
|
||||
|
||||
rkisp1_entities_unregister(rkisp1);
|
||||
if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
|
||||
if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
|
||||
rkisp1_csi_cleanup(rkisp1);
|
||||
rkisp1_debug_cleanup(rkisp1);
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
@ -53,6 +54,115 @@
|
||||
* +---------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Media block control (i.MX8MP only)
|
||||
*/
|
||||
|
||||
#define ISP_DEWARP_CONTROL 0x0138
|
||||
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY BIT(22)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_RISING (0 << 20)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_NEGATIVE (1 << 20)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE (2 << 20)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_FALLING (3 << 20)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK GENMASK(21, 20)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE BIT(19)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt) ((dt) << 13)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK GENMASK(18, 13)
|
||||
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY BIT(12)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_RISING (0 << 10)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_NEGATIVE (1 << 10)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE (2 << 10)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_FALLING (3 << 10)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK GENMASK(11, 10)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE BIT(9)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt) ((dt) << 3)
|
||||
#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK GENMASK(8, 3)
|
||||
|
||||
#define ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE BIT(1)
|
||||
#define ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE BIT(0)
|
||||
|
||||
static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
|
||||
struct media_pad *source)
|
||||
{
|
||||
struct v4l2_subdev *source_sd;
|
||||
struct v4l2_mbus_frame_desc fd;
|
||||
unsigned int dt;
|
||||
u32 mask;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Configure and enable the gasket with the CSI-2 data type. Set the
|
||||
* vsync polarity as active high, as that is what the ISP is configured
|
||||
* to expect in ISP_ACQ_PROP. Enable left justification, as the i.MX8MP
|
||||
* ISP has a 16-bit wide input and expects data to be left-aligned.
|
||||
*/
|
||||
|
||||
source_sd = media_entity_to_v4l2_subdev(source->entity);
|
||||
ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,
|
||||
source->index, &fd);
|
||||
if (ret) {
|
||||
dev_err(rkisp1->dev,
|
||||
"failed to get frame descriptor from '%s':%u: %d\n",
|
||||
source_sd->name, 0, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (fd.num_entries != 1) {
|
||||
dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",
|
||||
source_sd->name, 0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dt = fd.entry[0].bus.csi2.dt;
|
||||
|
||||
if (rkisp1->gasket_id == 0) {
|
||||
mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY
|
||||
| ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
|
||||
| ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
|
||||
val = ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt);
|
||||
} else {
|
||||
mask = ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY
|
||||
| ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
|
||||
| ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
|
||||
val = ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt);
|
||||
}
|
||||
|
||||
regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rkisp1_gasket_disable(struct rkisp1_device *rkisp1)
|
||||
{
|
||||
u32 mask;
|
||||
u32 val;
|
||||
|
||||
if (rkisp1->gasket_id == 1) {
|
||||
mask = ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
|
||||
| ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
|
||||
val = ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
|
||||
} else {
|
||||
mask = ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
|
||||
| ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
|
||||
| ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
|
||||
val = ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
|
||||
}
|
||||
|
||||
regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Camera Interface registers configurations
|
||||
*/
|
||||
@ -291,6 +401,9 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp)
|
||||
RKISP1_CIF_VI_IRCL_MIPI_SW_RST |
|
||||
RKISP1_CIF_VI_IRCL_ISP_SW_RST);
|
||||
rkisp1_write(rkisp1, RKISP1_CIF_VI_IRCL, 0x0);
|
||||
|
||||
if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP)
|
||||
rkisp1_gasket_disable(rkisp1);
|
||||
}
|
||||
|
||||
static void rkisp1_config_clk(struct rkisp1_isp *isp)
|
||||
@ -315,16 +428,24 @@ static void rkisp1_config_clk(struct rkisp1_isp *isp)
|
||||
}
|
||||
}
|
||||
|
||||
static void rkisp1_isp_start(struct rkisp1_isp *isp,
|
||||
struct v4l2_subdev_state *sd_state)
|
||||
static int rkisp1_isp_start(struct rkisp1_isp *isp,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct media_pad *source)
|
||||
{
|
||||
struct rkisp1_device *rkisp1 = isp->rkisp1;
|
||||
const struct v4l2_mbus_framefmt *src_fmt;
|
||||
const struct rkisp1_mbus_info *src_info;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
rkisp1_config_clk(isp);
|
||||
|
||||
if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP) {
|
||||
ret = rkisp1_gasket_enable(rkisp1, source);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Activate ISP */
|
||||
val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
|
||||
val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
|
||||
@ -338,6 +459,8 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp,
|
||||
|
||||
if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
|
||||
rkisp1_params_post_configure(&rkisp1->params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@ -848,7 +971,9 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
rkisp1_isp_start(isp, sd_state);
|
||||
ret = rkisp1_isp_start(isp, sd_state, source_pad);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = v4l2_subdev_call(rkisp1->source, video, s_stream, true);
|
||||
if (ret) {
|
||||
|
@ -144,6 +144,15 @@
|
||||
/* MI_INIT */
|
||||
#define RKISP1_CIF_MI_INIT_SKIP BIT(2)
|
||||
#define RKISP1_CIF_MI_INIT_SOFT_UPD BIT(4)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400 (0 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420 (1 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422 (2 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV444 (3 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12 (4 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8 (5 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_JPEG (6 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10 (7 << 5)
|
||||
#define RKISP1_CIF_MI_INIT_MP_OUTPUT_MASK (15 << 5)
|
||||
|
||||
/* MI_CTRL_SHD */
|
||||
#define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED BIT(0)
|
||||
@ -207,6 +216,24 @@
|
||||
#define RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP BIT(1)
|
||||
#define RKISP1_CIF_MI_XTD_FMT_CTRL_DMA_CB_CR_SWAP BIT(2)
|
||||
|
||||
/* MI_OUTPUT_ALIGN_FORMAT */
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT BIT(0)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES BIT(1)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_WORDS BIT(2)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_DWORDS BIT(3)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES BIT(4)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_WORDS BIT(5)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_DWORDS BIT(6)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_BYTES BIT(7)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_WORDS BIT(8)
|
||||
#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_DWORDS BIT(9)
|
||||
|
||||
/* MI_MP_OUTPUT_FIFO_SIZE */
|
||||
#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_FULL (0 << 0)
|
||||
#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_HALF (1 << 0)
|
||||
#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_QUARTER (2 << 0)
|
||||
#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_EIGHT (3 << 0)
|
||||
|
||||
/* VI_CCL */
|
||||
#define RKISP1_CIF_CCL_CIF_CLK_DIS BIT(2)
|
||||
/* VI_ISP_CLK_CTRL */
|
||||
@ -1000,6 +1027,15 @@
|
||||
#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000140)
|
||||
#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000144)
|
||||
#define RKISP1_CIF_MI_XTD_FORMAT_CTRL (RKISP1_CIF_MI_BASE + 0x00000148)
|
||||
#define RKISP1_CIF_MI_MP_HANDSHAKE_0 (RKISP1_CIF_MI_BASE + 0x0000014C)
|
||||
#define RKISP1_CIF_MI_MP_Y_LLENGTH (RKISP1_CIF_MI_BASE + 0x00000150)
|
||||
#define RKISP1_CIF_MI_MP_Y_SLICE_OFFSET (RKISP1_CIF_MI_BASE + 0x00000154)
|
||||
#define RKISP1_CIF_MI_MP_C_SLICE_OFFSET (RKISP1_CIF_MI_BASE + 0x00000158)
|
||||
#define RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT (RKISP1_CIF_MI_BASE + 0x0000015C)
|
||||
#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE (RKISP1_CIF_MI_BASE + 0x00000160)
|
||||
#define RKISP1_CIF_MI_MP_Y_PIC_WIDTH (RKISP1_CIF_MI_BASE + 0x00000164)
|
||||
#define RKISP1_CIF_MI_MP_Y_PIC_HEIGHT (RKISP1_CIF_MI_BASE + 0x00000168)
|
||||
#define RKISP1_CIF_MI_MP_Y_PIC_SIZE (RKISP1_CIF_MI_BASE + 0x0000016C)
|
||||
|
||||
#define RKISP1_CIF_SMIA_BASE 0x00001a00
|
||||
#define RKISP1_CIF_SMIA_CTRL (RKISP1_CIF_SMIA_BASE + 0x00000000)
|
||||
|
@ -444,11 +444,12 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
|
||||
sink_fmt = v4l2_subdev_state_get_format(sd_state, RKISP1_RSZ_PAD_SINK);
|
||||
sink_crop = v4l2_subdev_state_get_crop(sd_state, RKISP1_RSZ_PAD_SINK);
|
||||
|
||||
/* Not crop for MP bayer raw data */
|
||||
/* Not crop for MP bayer raw data, or for devices lacking dual crop. */
|
||||
mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
|
||||
|
||||
if (rsz->id == RKISP1_MAINPATH &&
|
||||
mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
|
||||
if ((rsz->id == RKISP1_MAINPATH &&
|
||||
mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) ||
|
||||
!rkisp1_has_feature(rsz->rkisp1, DUAL_CROP)) {
|
||||
sink_crop->left = 0;
|
||||
sink_crop->top = 0;
|
||||
sink_crop->width = sink_fmt->width;
|
||||
@ -631,21 +632,24 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
struct rkisp1_device *rkisp1 = rsz->rkisp1;
|
||||
struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
|
||||
enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
|
||||
bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
|
||||
struct v4l2_subdev_state *sd_state;
|
||||
|
||||
if (!enable) {
|
||||
rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
|
||||
if (rkisp1_has_feature(rkisp1, DUAL_CROP))
|
||||
rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
|
||||
rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (other->is_streaming)
|
||||
if (has_self_path && other->is_streaming)
|
||||
when = RKISP1_SHADOW_REGS_ASYNC;
|
||||
|
||||
sd_state = v4l2_subdev_lock_and_get_active_state(sd);
|
||||
|
||||
rkisp1_rsz_config(rsz, sd_state, when);
|
||||
rkisp1_dcrop_config(rsz, sd_state);
|
||||
if (rkisp1_has_feature(rkisp1, DUAL_CROP))
|
||||
rkisp1_dcrop_config(rsz, sd_state);
|
||||
|
||||
v4l2_subdev_unlock_state(sd_state);
|
||||
|
||||
@ -731,10 +735,11 @@ err_entity_cleanup:
|
||||
|
||||
int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
|
||||
{
|
||||
unsigned int dev_count = rkisp1_path_count(rkisp1);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
|
||||
for (i = 0; i < dev_count; i++) {
|
||||
struct rkisp1_resizer *rsz = &rkisp1->resizer_devs[i];
|
||||
|
||||
rsz->rkisp1 = rkisp1;
|
||||
|
@ -175,16 +175,21 @@
|
||||
/**
|
||||
* enum rkisp1_cif_isp_version - ISP variants
|
||||
*
|
||||
* @RKISP1_V10: used at least in rk3288 and rk3399
|
||||
* @RKISP1_V11: declared in the original vendor code, but not used
|
||||
* @RKISP1_V12: used at least in rk3326 and px30
|
||||
* @RKISP1_V13: used at least in rk1808
|
||||
* @RKISP1_V10: Used at least in RK3288 and RK3399.
|
||||
* @RKISP1_V11: Declared in the original vendor code, but not used. Same number
|
||||
* of entries in grids and histogram as v10.
|
||||
* @RKISP1_V12: Used at least in RK3326 and PX30.
|
||||
* @RKISP1_V13: Used at least in RK1808. Same number of entries in grids and
|
||||
* histogram as v12.
|
||||
* @RKISP1_V_IMX8MP: Used in at least i.MX8MP. Same number of entries in grids
|
||||
* and histogram as v10.
|
||||
*/
|
||||
enum rkisp1_cif_isp_version {
|
||||
RKISP1_V10 = 10,
|
||||
RKISP1_V11,
|
||||
RKISP1_V12,
|
||||
RKISP1_V13,
|
||||
RKISP1_V_IMX8MP,
|
||||
};
|
||||
|
||||
enum rkisp1_cif_isp_histogram_mode {
|
||||
@ -584,10 +589,9 @@ enum rkisp1_cif_isp_goc_mode {
|
||||
* as is reported by the hw_revision field of the struct media_device_info
|
||||
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
|
||||
*
|
||||
* Versions <= V11 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10
|
||||
* entries, versions >= V12 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12
|
||||
* entries. RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES is equal to the maximum
|
||||
* of the two.
|
||||
* V10 has RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10 entries, V12 has
|
||||
* RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 entries.
|
||||
* RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES is equal to the maximum of the two.
|
||||
*/
|
||||
struct rkisp1_cif_isp_goc_config {
|
||||
__u32 mode;
|
||||
@ -607,10 +611,10 @@ struct rkisp1_cif_isp_goc_config {
|
||||
* as is reported by the hw_revision field of the struct media_device_info
|
||||
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
|
||||
*
|
||||
* Versions <= V11 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10
|
||||
* entries, versions >= V12 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12
|
||||
* entries. RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE is equal to the maximum
|
||||
* of the two.
|
||||
* V10 has RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10 entries, V12 has
|
||||
* RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12 entries.
|
||||
* RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE is equal to the maximum of the
|
||||
* two.
|
||||
*/
|
||||
struct rkisp1_cif_isp_hst_config {
|
||||
__u32 mode;
|
||||
@ -902,9 +906,9 @@ struct rkisp1_cif_isp_bls_meas_val {
|
||||
* as is reported by the hw_revision field of the struct media_device_info
|
||||
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
|
||||
*
|
||||
* Versions <= V11 have RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries,
|
||||
* versions >= V12 have RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries.
|
||||
* RKISP1_CIF_ISP_AE_MEAN_MAX is equal to the maximum of the two.
|
||||
* V10 has RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries, V12 has
|
||||
* RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries. RKISP1_CIF_ISP_AE_MEAN_MAX is equal
|
||||
* to the maximum of the two.
|
||||
*
|
||||
* Image is divided into 5x5 blocks on V10 and 9x9 blocks on V12.
|
||||
*/
|
||||
@ -944,21 +948,21 @@ struct rkisp1_cif_isp_af_stat {
|
||||
* integer part.
|
||||
*
|
||||
* The window of the measurements area is divided to 5x5 sub-windows for
|
||||
* V10/V11 and to 9x9 sub-windows for V12. The histogram is then computed for
|
||||
* each sub-window independently and the final result is a weighted average of
|
||||
* the histogram measurements on all sub-windows. The window of the
|
||||
* measurements area and the weight of each sub-window are configurable using
|
||||
* V10 and to 9x9 sub-windows for V12. The histogram is then computed for each
|
||||
* sub-window independently and the final result is a weighted average of the
|
||||
* histogram measurements on all sub-windows. The window of the measurements
|
||||
* area and the weight of each sub-window are configurable using
|
||||
* struct @rkisp1_cif_isp_hst_config.
|
||||
*
|
||||
* The histogram contains 16 bins in V10/V11 and 32 bins in V12/V13.
|
||||
* The histogram contains 16 bins in V10 and 32 bins in V12.
|
||||
*
|
||||
* The number of entries of @hist_bins depends on the hardware revision
|
||||
* as is reported by the hw_revision field of the struct media_device_info
|
||||
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
|
||||
*
|
||||
* Versions <= V11 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 entries,
|
||||
* versions >= V12 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 entries.
|
||||
* RKISP1_CIF_ISP_HIST_BIN_N_MAX is equal to the maximum of the two.
|
||||
* V10 has RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 entries, V12 has
|
||||
* RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 entries. RKISP1_CIF_ISP_HIST_BIN_N_MAX is
|
||||
* equal to the maximum of the two.
|
||||
*/
|
||||
struct rkisp1_cif_isp_hist_stat {
|
||||
__u32 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
|
||||
|
Loading…
x
Reference in New Issue
Block a user