void s3c_fimc_set_output_dma(struct s3c_fimc_control *ctrl) { struct s3c_fimc_out_frame *frame = &ctrl->out_frame; u32 cfg; /* for offsets */ cfg = 0; cfg |= S3C_CIOYOFF_HORIZONTAL(frame->offset.y_h); cfg |= S3C_CIOYOFF_VERTICAL(frame->offset.y_v); writel(cfg, ctrl->regs + S3C_CIOYOFF); cfg = 0; cfg |= S3C_CIOCBOFF_HORIZONTAL(frame->offset.cb_h); cfg |= S3C_CIOCBOFF_VERTICAL(frame->offset.cb_v); writel(cfg, ctrl->regs + S3C_CIOCBOFF); cfg = 0; cfg |= S3C_CIOCROFF_HORIZONTAL(frame->offset.cr_h); cfg |= S3C_CIOCROFF_VERTICAL(frame->offset.cr_v); writel(cfg, ctrl->regs + S3C_CIOCROFF); /* for original size */ s3c_fimc_set_output_dma_size(ctrl); /* for output dma control */ cfg = readl(ctrl->regs + S3C_CIOCTRL); cfg &= ~(S3C_CIOCTRL_ORDER2P_MASK | S3C_CIOCTRL_ORDER422_MASK | \ S3C_CIOCTRL_YCBCR_PLANE_MASK); if (frame->planes == 1) cfg |= frame->order_1p; else if (frame->planes == 2) cfg |= (S3C_CIOCTRL_YCBCR_2PLANE | \ (frame->order_2p << S3C_CIOCTRL_ORDER2P_SHIFT)); else if (frame->planes == 3) cfg |= S3C_CIOCTRL_YCBCR_3PLANE; writel(cfg, ctrl->regs + S3C_CIOCTRL); }
int fimc50_hwset_output_offset(struct fimc_control *ctrl, u32 pixelformat, struct v4l2_rect *bounds, struct v4l2_rect *crop) { u32 cfg_y = 0, cfg_cb = 0, cfg_cr = 0; if (!crop->left && !crop->top && (bounds->width == crop->width) && (bounds->height == crop->height)) return -EINVAL; fimc_dbg("%s: left: %d, top: %d, width: %d, height: %d\n", __func__, crop->left, crop->top, crop->width, crop->height); switch (pixelformat) { /* 1 plane, 32 bits per pixel */ case V4L2_PIX_FMT_RGB32: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); break; /* 1 plane, 16 bits per pixel */ case V4L2_PIX_FMT_YUYV: /* fall through */ case V4L2_PIX_FMT_UYVY: /* fall through */ case V4L2_PIX_FMT_VYUY: /* fall through */ case V4L2_PIX_FMT_YVYU: /* fall through */ case V4L2_PIX_FMT_RGB565: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); break; /* 2 planes, 16 bits per pixel */ case V4L2_PIX_FMT_NV16: /* fall through */ case V4L2_PIX_FMT_NV61: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top); break; /* 2 planes, 12 bits per pixel */ case V4L2_PIX_FMT_NV12: /* fall through */ case V4L2_PIX_FMT_NV12T: /* fall through */ case V4L2_PIX_FMT_NV21: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top); break; /* 3 planes, 16 bits per pixel */ case V4L2_PIX_FMT_YUV422P: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top); cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left); cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top); break; /* 3 planes, 12 bits per pixel */ case V4L2_PIX_FMT_YUV420: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top); cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left); cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top); break; default: break; } writel(cfg_y, ctrl->regs + S3C_CIOYOFF); writel(cfg_cb, ctrl->regs + S3C_CIOCBOFF); writel(cfg_cr, ctrl->regs + S3C_CIOCROFF); return 0; }
/* FIXME */ int fimc_hwset_output_offset(struct fimc_control *ctrl, u32 pixelformat, struct v4l2_rect *bounds, struct v4l2_rect *crop) { u32 cfg_y = 0, cfg_cb = 0, cfg_cr = 0; /* This check routine is disabled. * If the CIOYOFFn value have to be changed to 0 from other value, * this operation can be blocked by below check routine. if (!crop->left && !crop->top && (bounds->width == crop->width) && (bounds->height == crop->height)) return -EINVAL; */ fimc_dbg("%s: left: %d, top: %d, width: %d, height: %d\n", __func__, crop->left, crop->top, crop->width, crop->height); switch (pixelformat) { /* 1 plane, 32 bits per pixel */ case V4L2_PIX_FMT_RGB32: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left * 4); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); break; /* 1 plane, 16 bits per pixel */ case V4L2_PIX_FMT_YUYV: /* fall through */ case V4L2_PIX_FMT_UYVY: /* fall through */ case V4L2_PIX_FMT_VYUY: /* fall through */ case V4L2_PIX_FMT_YVYU: /* fall through */ case V4L2_PIX_FMT_RGB565: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left * 2); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); break; /* 2 planes, 16 bits per pixel */ case V4L2_PIX_FMT_NV16: /* fall through */ case V4L2_PIX_FMT_NV61: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 2); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 2); break; /* 2 planes, 12 bits per pixel */ case V4L2_PIX_FMT_NV12: /* fall through */ case V4L2_PIX_FMT_NV12T: /* fall through */ case V4L2_PIX_FMT_NV21: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 4); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 4); break; /* 3 planes, 16 bits per pixel */ case V4L2_PIX_FMT_YUV422P: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 2); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 2); cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left / 2); cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top / 2); break; /* 3 planes, 12 bits per pixel */ case V4L2_PIX_FMT_YUV420: cfg_y |= S3C_CIOYOFF_HORIZONTAL(crop->left); cfg_y |= S3C_CIOYOFF_VERTICAL(crop->top); cfg_cb |= S3C_CIOCBOFF_HORIZONTAL(crop->left / 4); cfg_cb |= S3C_CIOCBOFF_VERTICAL(crop->top / 4); cfg_cr |= S3C_CIOCROFF_HORIZONTAL(crop->left / 4); cfg_cr |= S3C_CIOCROFF_VERTICAL(crop->top / 4); break; default: break; } writel(cfg_y, ctrl->regs + S3C_CIOYOFF); writel(cfg_cb, ctrl->regs + S3C_CIOCBOFF); writel(cfg_cr, ctrl->regs + S3C_CIOCROFF); return 0; }