Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 271787
b: refs/heads/master
c: ee7160e
h: refs/heads/master
i:
  271785: ece6370
  271783: 7fed342
v: v3
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Sep 6, 2011
1 parent 54a9b55 commit 2eb742b
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 237e026559b7cd03fc575b6007cea11aef9e0aa6
refs/heads/master: ee7160e57c98ffb03253abb2cb4ad5b1376a2257
17 changes: 16 additions & 1 deletion trunk/drivers/media/video/s5p-fimc/fimc-capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static int fimc_init_capture(struct fimc_dev *fimc)
fimc_hw_set_mainscaler(ctx);
fimc_hw_set_target_format(ctx);
fimc_hw_set_rotation(ctx);
fimc_hw_set_effect(ctx);
fimc_hw_set_effect(ctx, false);
fimc_hw_set_output_path(ctx);
fimc_hw_set_out_dma(ctx);
clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
Expand Down Expand Up @@ -731,6 +731,17 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
return 0;
}

static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx, bool jpeg)
{
ctx->scaler.enabled = !jpeg;
fimc_ctrls_activate(ctx, !jpeg);

if (jpeg)
set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
else
clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
}

static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
{
struct fimc_ctx *ctx = fimc->vid_cap.ctx;
Expand Down Expand Up @@ -783,6 +794,8 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
if (!(ctx->state & FIMC_DST_CROP))
set_frame_crop(ff, 0, 0, pix->width, pix->height);

fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color));

/* Reset cropping and set format at the camera interface input */
if (!fimc->vid_cap.user_subdev_api) {
ctx->s_frame.fmt = s_fmt;
Expand Down Expand Up @@ -1133,6 +1146,8 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
*mf = fmt->format;
return 0;
}
fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color));

ff = fmt->pad == FIMC_SD_PAD_SINK ?
&ctx->s_frame : &ctx->d_frame;

Expand Down
70 changes: 36 additions & 34 deletions trunk/drivers/media/video/s5p-fimc/fimc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,22 +159,28 @@ static struct fimc_fmt fimc_formats[] = {
.memplanes = 2,
.colplanes = 2,
.flags = FMT_FLAGS_M2M,
}, {
.name = "JPEG encoded data",
.fourcc = V4L2_PIX_FMT_JPEG,
.color = S5P_FIMC_JPEG,
.depth = { 8 },
.memplanes = 1,
.colplanes = 1,
.mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
.flags = FMT_FLAGS_CAM,
},
};

int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot)
int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
int dw, int dh, int rotation)
{
int tx, ty;
if (rotation == 90 || rotation == 270)
swap(dw, dh);

if (rot == 90 || rot == 270) {
ty = dw;
tx = dh;
} else {
tx = dw;
ty = dh;
}
if (!ctx->scaler.enabled)
return (sw == dw && sh == dh) ? 0 : -EINVAL;

if ((sw >= SCALER_MAX_HRATIO * tx) || (sh >= SCALER_MAX_VRATIO * ty))
if ((sw >= SCALER_MAX_HRATIO * dw) || (sh >= SCALER_MAX_VRATIO * dh))
return -EINVAL;

return 0;
Expand Down Expand Up @@ -321,15 +327,15 @@ static int stop_streaming(struct vb2_queue *q)
return 0;
}

static void fimc_capture_irq_handler(struct fimc_dev *fimc)
void fimc_capture_irq_handler(struct fimc_dev *fimc, bool final)
{
struct fimc_vid_cap *cap = &fimc->vid_cap;
struct fimc_vid_buffer *v_buf;
struct timeval *tv;
struct timespec ts;

if (!list_empty(&cap->active_buf_q) &&
test_bit(ST_CAPT_RUN, &fimc->state)) {
test_bit(ST_CAPT_RUN, &fimc->state) && final) {
ktime_get_real_ts(&ts);

v_buf = active_queue_pop(cap);
Expand Down Expand Up @@ -364,7 +370,8 @@ static void fimc_capture_irq_handler(struct fimc_dev *fimc)
}

if (cap->active_buf_cnt == 0) {
clear_bit(ST_CAPT_RUN, &fimc->state);
if (final)
clear_bit(ST_CAPT_RUN, &fimc->state);

if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
cap->buf_index = 0;
Expand Down Expand Up @@ -407,14 +414,12 @@ static irqreturn_t fimc_irq_handler(int irq, void *priv)
spin_unlock(&ctx->slock);
}
return IRQ_HANDLED;
} else {
if (test_bit(ST_CAPT_PEND, &fimc->state)) {
fimc_capture_irq_handler(fimc);

if (cap->active_buf_cnt == 1) {
fimc_deactivate_capture(fimc);
clear_bit(ST_CAPT_STREAM, &fimc->state);
}
} else if (test_bit(ST_CAPT_PEND, &fimc->state)) {
fimc_capture_irq_handler(fimc,
!test_bit(ST_CAPT_JPEG, &fimc->state));
if (cap->active_buf_cnt == 1) {
fimc_deactivate_capture(fimc);
clear_bit(ST_CAPT_STREAM, &fimc->state);
}
}
out:
Expand Down Expand Up @@ -586,9 +591,6 @@ int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
fimc_set_yuv_order(ctx);
}

/* Input DMA mode is not allowed when the scaler is disabled. */
ctx->scaler.enabled = 1;

if (flags & FIMC_SRC_ADDR) {
vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
ret = fimc_prepare_addr(ctx, vb, s_frame, &s_frame->paddr);
Expand Down Expand Up @@ -643,7 +645,7 @@ static void fimc_dma_run(void *priv)
fimc_hw_set_mainscaler(ctx);
fimc_hw_set_target_format(ctx);
fimc_hw_set_rotation(ctx);
fimc_hw_set_effect(ctx);
fimc_hw_set_effect(ctx, false);
}

fimc_hw_set_output_path(ctx);
Expand Down Expand Up @@ -773,7 +775,7 @@ static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_ROTATE:
if (fimc_capture_pending(fimc) ||
fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
ret = fimc_check_scaler_ratio(ctx->s_frame.width,
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
ctx->s_frame.height, ctx->d_frame.width,
ctx->d_frame.height, ctrl->val);
}
Expand Down Expand Up @@ -1098,6 +1100,8 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,

fimc_fill_frame(frame, f);

ctx->scaler.enabled = 1;

if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
else
Expand Down Expand Up @@ -1269,15 +1273,13 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
/* Check to see if scaling ratio is within supported range */
if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height,
ctx->d_frame.width,
ctx->d_frame.height,
ctx->rotation);
ret = fimc_check_scaler_ratio(ctx, cr->c.width,
cr->c.height, ctx->d_frame.width,
ctx->d_frame.height, ctx->rotation);
} else {
ret = fimc_check_scaler_ratio(ctx->s_frame.width,
ctx->s_frame.height,
cr->c.width, cr->c.height,
ctx->rotation);
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
ctx->s_frame.height, cr->c.width,
cr->c.height, ctx->rotation);
}
if (ret) {
v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
Expand Down
7 changes: 5 additions & 2 deletions trunk/drivers/media/video/s5p-fimc/fimc-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum fimc_dev_flags {
ST_CAPT_SHUT,
ST_CAPT_BUSY,
ST_CAPT_APPLY_CFG,
ST_CAPT_JPEG,
};

#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
Expand Down Expand Up @@ -669,7 +670,7 @@ void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
void fimc_hw_en_capture(struct fimc_ctx *ctx);
void fimc_hw_set_effect(struct fimc_ctx *ctx);
void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active);
void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
void fimc_hw_set_input_path(struct fimc_ctx *ctx);
void fimc_hw_set_output_path(struct fimc_ctx *ctx);
Expand Down Expand Up @@ -697,14 +698,16 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code,
unsigned int mask, int index);

int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot);
int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
int dw, int dh, int rotation);
int fimc_set_scaler_info(struct fimc_ctx *ctx);
int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
struct fimc_frame *frame, struct fimc_addr *paddr);
void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
void fimc_set_yuv_order(struct fimc_ctx *ctx);
void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
void fimc_capture_irq_handler(struct fimc_dev *fimc, bool done);

int fimc_register_m2m_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev);
Expand Down
31 changes: 21 additions & 10 deletions trunk/drivers/media/video/s5p-fimc/fimc-reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,17 +352,19 @@ void fimc_hw_en_capture(struct fimc_ctx *ctx)
writel(cfg | S5P_CIIMGCPT_IMGCPTEN, dev->regs + S5P_CIIMGCPT);
}

void fimc_hw_set_effect(struct fimc_ctx *ctx)
void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active)
{
struct fimc_dev *dev = ctx->fimc_dev;
struct fimc_effect *effect = &ctx->effect;
u32 cfg = (S5P_CIIMGEFF_IE_ENABLE | S5P_CIIMGEFF_IE_SC_AFTER);

cfg |= effect->type;
u32 cfg = 0;

if (effect->type == S5P_FIMC_EFFECT_ARBITRARY) {
cfg |= S5P_CIIMGEFF_PAT_CB(effect->pat_cb);
cfg |= S5P_CIIMGEFF_PAT_CR(effect->pat_cr);
if (active) {
cfg |= S5P_CIIMGEFF_IE_SC_AFTER | S5P_CIIMGEFF_IE_ENABLE;
cfg |= effect->type;
if (effect->type == S5P_FIMC_EFFECT_ARBITRARY) {
cfg |= S5P_CIIMGEFF_PAT_CB(effect->pat_cb);
cfg |= S5P_CIIMGEFF_PAT_CR(effect->pat_cr);
}
}

writel(cfg, dev->regs + S5P_CIIMGEFF);
Expand Down Expand Up @@ -592,6 +594,9 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
else if (bus_width == 16)
cfg |= S5P_CISRCFMT_ITU601_16BIT;
} /* else defaults to ITU-R BT.656 8-bit */
} else if (cam->bus_type == FIMC_MIPI_CSI2) {
if (fimc_fmt_is_jpeg(f->fmt->color))
cfg |= S5P_CISRCFMT_ITU601_8BIT;
}

cfg |= S5P_CISRCFMT_HSIZE(f->o_width) | S5P_CISRCFMT_VSIZE(f->o_height);
Expand Down Expand Up @@ -633,7 +638,7 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
/* Select ITU B interface, disable Writeback path and test pattern. */
cfg &= ~(S5P_CIGCTRL_TESTPAT_MASK | S5P_CIGCTRL_SELCAM_ITU_A |
S5P_CIGCTRL_SELCAM_MIPI | S5P_CIGCTRL_CAMIF_SELWB |
S5P_CIGCTRL_SELCAM_MIPI_A);
S5P_CIGCTRL_SELCAM_MIPI_A | S5P_CIGCTRL_CAM_JPEG);

if (cam->bus_type == FIMC_MIPI_CSI2) {
cfg |= S5P_CIGCTRL_SELCAM_MIPI;
Expand All @@ -642,9 +647,15 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
cfg |= S5P_CIGCTRL_SELCAM_MIPI_A;

/* TODO: add remaining supported formats. */
if (vid_cap->mf.code == V4L2_MBUS_FMT_VYUY8_2X8) {
switch (vid_cap->mf.code) {
case V4L2_MBUS_FMT_VYUY8_2X8:
tmp = S5P_CSIIMGFMT_YCBCR422_8BIT;
} else {
break;
case V4L2_MBUS_FMT_JPEG_1X8:
tmp = S5P_CSIIMGFMT_USER(1);
cfg |= S5P_CIGCTRL_CAM_JPEG;
break;
default:
v4l2_err(fimc->vid_cap.vfd,
"Not supported camera pixel format: %d",
vid_cap->mf.code);
Expand Down
8 changes: 3 additions & 5 deletions trunk/drivers/media/video/s5p-fimc/regs-fimc.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define S5P_CIGCTRL_IRQ_CLR (1 << 19)
#define S5P_CIGCTRL_IRQ_ENABLE (1 << 16)
#define S5P_CIGCTRL_SHDW_DISABLE (1 << 12)
#define S5P_CIGCTRL_CAM_JPEG (1 << 8)
#define S5P_CIGCTRL_SELCAM_MIPI_A (1 << 7)
#define S5P_CIGCTRL_CAMIF_SELWB (1 << 6)
/* 0 - ITU601; 1 - ITU709 */
Expand Down Expand Up @@ -184,7 +185,6 @@

/* Image effect */
#define S5P_CIIMGEFF 0xd0
#define S5P_CIIMGEFF_IE_DISABLE (0 << 30)
#define S5P_CIIMGEFF_IE_ENABLE (1 << 30)
#define S5P_CIIMGEFF_IE_SC_BEFORE (0 << 29)
#define S5P_CIIMGEFF_IE_SC_AFTER (1 << 29)
Expand Down Expand Up @@ -286,10 +286,8 @@
#define S5P_CSIIMGFMT_RAW8 0x2a
#define S5P_CSIIMGFMT_RAW10 0x2b
#define S5P_CSIIMGFMT_RAW12 0x2c
#define S5P_CSIIMGFMT_USER1 0x30
#define S5P_CSIIMGFMT_USER2 0x31
#define S5P_CSIIMGFMT_USER3 0x32
#define S5P_CSIIMGFMT_USER4 0x33
/* User defined formats. x = 0...16. */
#define S5P_CSIIMGFMT_USER(x) (0x30 + x - 1)

/* Output frame buffer sequence mask */
#define S5P_CIFCNTSEQ 0x1FC
Expand Down

0 comments on commit 2eb742b

Please sign in to comment.