@@ -48,14 +48,17 @@ enum rkisp1_plane {
* @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;
u32 uv_swap : 1;
u32 yc_swap : 1;
+ u32 byte_swap : 1;
u32 write_format;
u32 output_format;
u32 mbus;
@@ -96,42 +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 */
@@ -139,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 */
@@ -146,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,
},
};
@@ -484,11 +522,16 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
*/
if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
- if (cap->pix.cfg->yc_swap)
+ 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);
@@ -951,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 (!has_self_path || !other->is_streaming) {
- /* force cfg update */
- rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
- RKISP1_CIF_MI_INIT_SOFT_UPD);
+ 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);
@@ -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)