Exemplo n.º 1
0
static int gsc_cap_config_camclk(struct gsc_dev *gsc,
		struct exynos_isp_info *isp_info, int i)
{
	struct gsc_capture_device *gsc_cap = &gsc->cap;
	struct clk *camclk;
	struct clk *srclk;

	camclk = clk_get(&gsc->pdev->dev, isp_info->cam_clk_name);
	if (IS_ERR_OR_NULL(camclk)) {
		gsc_err("failed to get cam clk");
		return -ENXIO;
	}
	gsc_cap->sensor[i].camclk = camclk;

	srclk = clk_get(&gsc->pdev->dev, isp_info->cam_srclk_name);
	if (IS_ERR_OR_NULL(srclk)) {
		clk_put(camclk);
		gsc_err("failed to get cam source clk\n");
		return -ENXIO;
	}
	clk_set_parent(camclk, srclk);
	clk_set_rate(camclk, isp_info->clk_frequency);
	clk_put(srclk);

	return 0;
}
Exemplo n.º 2
0
void gsc_op_timer_handler(unsigned long arg)
{
	struct gsc_dev *gsc = (struct gsc_dev *)arg;
	struct gsc_ctx *ctx = v4l2_m2m_get_curr_priv(gsc->m2m.m2m_dev);
	struct vb2_buffer *src_vb, *dst_vb;

	if (!test_bit(ST_M2M_RUN, &gsc->state)) {
		gsc_warn("gsc state is 0x%lx", gsc->state);
		return;
	}

	gsc_dump_registers(gsc);

	clear_bit(ST_M2M_RUN, &gsc->state);
	pm_runtime_put(&gsc->pdev->dev);

	src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
	dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
	if (src_vb && dst_vb) {
		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
	}
	gsc_err("GSCALER[%d] interrupt hasn't been triggered", gsc->id);
	gsc_err("erro ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
}
Exemplo n.º 3
0
void gsc_op_timer_handler(unsigned long arg)
{
	struct gsc_dev *gsc = (struct gsc_dev *)arg;
	struct gsc_ctx *ctx = v4l2_m2m_get_curr_priv(gsc->m2m.m2m_dev);
	struct vb2_buffer *src_vb, *dst_vb;
#ifdef GSC_PERF
	gsc->end_time = sched_clock();
	gsc_err("expire time: %llu\n", gsc->end_time - gsc->start_time);
#endif
	gsc_dump_registers(gsc);
	exynos_iommu_dump_status(&gsc->pdev->dev);

	clear_bit(ST_M2M_RUN, &gsc->state);
	pm_runtime_put(&gsc->pdev->dev);
	gsc->runtime_put_cnt++;

	src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
	dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
	if (src_vb && dst_vb) {
		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
	}
	gsc_err("GSCALER[%d] interrupt hasn't been triggered", gsc->id);
	gsc_err("erro ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
}
Exemplo n.º 4
0
int gsc_fill_addr(struct gsc_ctx *ctx)
{
	struct gsc_frame *s_frame, *d_frame;
	struct vb2_buffer *vb = NULL;
	int ret = 0;

	s_frame = &ctx->s_frame;
	d_frame = &ctx->d_frame;

	vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
	if (vb->num_planes != s_frame->fmt->num_planes) {
		gsc_err(" vb(%p) planes=%d s_frame(%p) planes=%d\n",
			vb, vb->num_planes, s_frame, s_frame->fmt->num_planes);
		return -EINVAL;
	}
	ret = gsc_prepare_addr(ctx, vb, s_frame, &s_frame->addr);
	if (ret)
		return ret;

	vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
	if (vb->num_planes != d_frame->fmt->num_planes) {
		gsc_err("vb(%p) planes=%d d_frame(%p) planes=%d\n",
			vb, vb->num_planes, d_frame, d_frame->fmt->num_planes);
		return -EINVAL;
	}
	ret = gsc_prepare_addr(ctx, vb, d_frame, &d_frame->addr);

	return ret;
}
Exemplo n.º 5
0
static int gsc_capture_streamon(struct file *file, void *priv,
				enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_pipeline *p = &gsc->pipeline;
	int ret;

	if (gsc_cap_active(gsc))
		return -EBUSY;

	if (p->disp) {
		gsc_pm_qos_ctrl(gsc, GSC_QOS_ON, 267000, 200000);
		media_entity_pipeline_start(&p->disp->entity, p->pipe);
	} else if (p->sensor) {
		media_entity_pipeline_start(&p->sensor->entity, p->pipe);
	} else {
		gsc_err("Error pipeline");
		return -EPIPE;
	}

	ret = gsc_cap_link_validate(gsc);
	if (ret)
		return ret;

	gsc_hw_set_sw_reset(gsc);
	ret= gsc_wait_reset(gsc);
	if (ret < 0) {
		gsc_err("gscaler s/w reset timeout");
		return ret;
	}
	gsc_hw_set_output_buf_mask_all(gsc);
	return vb2_streamon(&gsc->cap.vbq, type);
}
Exemplo n.º 6
0
int gsc_set_scaler_info(struct gsc_ctx *ctx)
{
	struct gsc_scaler *sc = &ctx->scaler;
	struct gsc_frame *s_frame = &ctx->s_frame;
	struct gsc_frame *d_frame = &ctx->d_frame;
	struct gsc_variant *variant = ctx->gsc_dev->variant;
	int tx, ty;
	int ret;

	ret = gsc_check_scaler_ratio(variant, s_frame->crop.width,
		s_frame->crop.height, d_frame->crop.width, d_frame->crop.height,
		ctx->gsc_ctrls.rotate->val, ctx->out_path);
	if (ret) {
		gsc_err("out of scaler range");
		return ret;
	}

	if (ctx->gsc_ctrls.rotate->val == 90 ||
	    ctx->gsc_ctrls.rotate->val == 270) {
		ty = d_frame->crop.width;
		tx = d_frame->crop.height;
	} else {
		tx = d_frame->crop.width;
		ty = d_frame->crop.height;
	}

	ret = gsc_cal_prescaler_ratio(variant, s_frame->crop.width,
				      tx, &sc->pre_hratio);
	if (ret) {
		gsc_err("Horizontal scale ratio is out of range");
		return ret;
	}

	ret = gsc_cal_prescaler_ratio(variant, s_frame->crop.height,
				      ty, &sc->pre_vratio);
	if (ret) {
		gsc_err("Vertical scale ratio is out of range");
		return ret;
	}

	gsc_check_src_scale_info(variant, s_frame, &sc->pre_hratio,
				 tx, ty, &sc->pre_vratio);

	gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio,
				   &sc->pre_shfactor);

	sc->main_hratio = (s_frame->crop.width << 16) / tx;
	sc->main_vratio = (s_frame->crop.height << 16) / ty;

	gsc_dbg("scaler input/output size : sx = %d, sy = %d, tx = %d, ty = %d",
		s_frame->crop.width, s_frame->crop.height, tx, ty);
	gsc_dbg("scaler ratio info : pre_shfactor : %d, pre_h : %d, pre_v :%d,\
		main_h : %ld, main_v : %ld", sc->pre_shfactor, sc->pre_hratio,
		sc->pre_vratio, sc->main_hratio, sc->main_vratio);

	return 0;
}
static int gsc_capture_queue_setup(struct vb2_queue *vq,
			const struct v4l2_format *fmt, unsigned int *num_buffers,
			unsigned int *num_planes, unsigned int sizes[],
			void *allocators[])
{
	struct gsc_ctx *ctx = vq->drv_priv;
	struct gsc_fmt *ffmt = ctx->d_frame.fmt;
	int i, ret = 0;

	if (!ffmt)
		return -EINVAL;

	*num_planes = ffmt->num_planes;

	for (i = 0; i < ffmt->num_planes; i++) {
		sizes[i] = get_plane_size(&ctx->d_frame, i);
		allocators[i] = ctx->gsc_dev->alloc_ctx;
	}

	ret = vb2_queue_init(vq);
	if (ret) {
		gsc_err("failed to init vb2_queue");
		return ret;
	}

	return 0;
}
Exemplo n.º 8
0
static int gsc_capture_s_fmt_mplane(struct file *file, void *fh,
				 struct v4l2_format *f)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_ctx *ctx = gsc->cap.ctx;
	struct gsc_frame *frame;
	struct v4l2_pix_format_mplane *pix;
	int i, ret = 0;

	ret = gsc_capture_try_fmt_mplane(file, fh, f);
	if (ret)
		return ret;

	if (vb2_is_streaming(&gsc->cap.vbq)) {
		gsc_err("queue (%d) busy", f->type);
		return -EBUSY;
	}

	frame = &ctx->d_frame;

	pix = &f->fmt.pix_mp;
	frame->fmt = find_format(&pix->pixelformat, NULL, 0);
	if (!frame->fmt)
		return -EINVAL;

	for (i = 0; i < frame->fmt->nr_comp; i++)
		frame->payload[i] =
			pix->plane_fmt[i].bytesperline * pix->height;

	gsc_set_frame_size(frame, pix->width, pix->height);

	gsc_dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);

	return 0;
}
Exemplo n.º 9
0
static int gsc_capture_streamon(struct file *file, void *priv,
				enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_pipeline *p = &gsc->pipeline;
	int ret;

	if (gsc_cap_active(gsc))
		return -EBUSY;

	if (p->disp) {
		media_entity_pipeline_start(&p->disp->entity, p->pipe);
	} else if (p->sensor) {
		media_entity_pipeline_start(&p->sensor->entity, p->pipe);
	} else {
		gsc_err("Error pipeline");
		return -EPIPE;
	}

	ret = gsc_cap_link_validate(gsc);
	if (ret)
		return ret;

	return vb2_streamon(&gsc->cap.vbq, type);
}
Exemplo n.º 10
0
static int gsc_m2m_release(struct file *file)
{
	struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
	struct gsc_dev *gsc = ctx->gsc_dev;

	gsc_dbg("pid: %d, state: 0x%lx, refcnt= %d",
		task_pid_nr(current), gsc->state, gsc->m2m.refcnt);

	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	gsc_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	if (--gsc->m2m.refcnt <= 0)
		clear_bit(ST_M2M_OPEN, &gsc->state);

	/* This is unnormal case */
	if (gsc->protected_content) {
		int id = gsc->id + 3;
		gsc_err("DRM should be disabled before device close");
		exynos_smc(SMC_PROTECTION_SET, 0, id, 0);
		gsc_set_protected_content(gsc, false);
	}

	kfree(ctx);
	return 0;
}
Exemplo n.º 11
0
int gsc_wait_stop(struct gsc_dev *dev)
{
	unsigned long timeo = jiffies + 10; /* timeout of 50ms */
	u32 cfg;
	int ret;

	while (time_before(jiffies, timeo)) {
		cfg = readl(dev->regs + GSC_ENABLE);
		if (!(cfg & GSC_ENABLE_OP_STATUS))
			return 0;
		usleep_range(10, 20);
	}
	/* This is workaround until next chips.
	 * If fimd is stop than gsc, gsc didn't work complete
	 */
	gsc_hw_set_sw_reset(dev);
	ret = gsc_wait_reset(dev);
	if (ret < 0) {
		gsc_err("gscaler s/w reset timeout");
		return ret;
	}
	gsc_hw_set_pixelasync_reset_output(dev);
	gsc_info("wait time : %d ms", jiffies_to_msecs(jiffies - timeo + 10));

	return 0;
}
Exemplo n.º 12
0
static int gsc_capture_streamoff(struct file *file, void *priv,
			    enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct v4l2_subdev *sd;
	struct gsc_pipeline *p = &gsc->pipeline;
	int ret;

	if (p->disp) {
		gsc_pm_qos_ctrl(gsc, GSC_QOS_OFF, 0, 0);
		sd = gsc->pipeline.disp;
	} else if (p->sensor) {
		sd = gsc->pipeline.sensor;
	} else {
		gsc_err("Error pipeline");
		return -EPIPE;
	}

	ret = vb2_streamoff(&gsc->cap.vbq, type);
	if (ret == 0) {
		if (p->disp)
			media_entity_pipeline_stop(&p->disp->entity);
		else if (p->sensor)
			media_entity_pipeline_stop(&p->sensor->entity);
	}

	return ret;
}
Exemplo n.º 13
0
static int gsc_m2m_open(struct file *file)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_ctx *ctx = NULL;
	int ret;

	gsc_dbg("pid: %d, state: 0x%lx", task_pid_nr(current), gsc->state);

	if (gsc_out_opened(gsc) || gsc_cap_opened(gsc))
		return -EBUSY;

	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	v4l2_fh_init(&ctx->fh, gsc->m2m.vfd);

	ret = gsc_ctrls_create(ctx);
	if (ret)
		goto error_fh;

	/* Use separate control handler per file handle */
	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
	file->private_data = &ctx->fh;
	v4l2_fh_add(&ctx->fh);

	ctx->gsc_dev = gsc;
	/* Default color format */
	ctx->s_frame.fmt = get_format(0);
	ctx->d_frame.fmt = get_format(0);
	/* Setup the device context for mem2mem mode. */
	ctx->state |= GSC_CTX_M2M;
	ctx->flags = 0;
	ctx->in_path = GSC_DMA;
	ctx->out_path = GSC_DMA;
	spin_lock_init(&ctx->slock);

	INIT_LIST_HEAD(&ctx->fence_wait_list);
	INIT_WORK(&ctx->fence_work, gsc_m2m_fence_work);

	ctx->m2m_ctx = v4l2_m2m_ctx_init(gsc->m2m.m2m_dev, ctx, queue_init);
	if (IS_ERR(ctx->m2m_ctx)) {
		gsc_err("Failed to initialize m2m context");
		ret = PTR_ERR(ctx->m2m_ctx);
		goto error_fh;
	}

	if (gsc->m2m.refcnt++ == 0)
		set_bit(ST_M2M_OPEN, &gsc->state);

	gsc_dbg("gsc m2m driver is opened, ctx(0x%p)", ctx);
	return 0;

error_fh:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
	return ret;
}
Exemplo n.º 14
0
static int gsc_capture_create_link(struct gsc_dev *gsc)
{
	struct media_entity *source, *sink;
	struct exynos_platform_gscaler *pdata = gsc->pdata;
	struct exynos_isp_info *isp_info;
	u32 num_clients = pdata->num_clients;
	int ret, i;
	enum cam_port id;

	/* GSC-SUBDEV ------> GSC-VIDEO (Always link enable) */
	source = &gsc->cap.sd_cap->entity;
	sink = &gsc->cap.vfd->entity;
	if (source && sink) {
		ret = media_entity_create_link(source, GSC_PAD_SOURCE, sink,
				0, MEDIA_LNK_FL_IMMUTABLE |
				MEDIA_LNK_FL_ENABLED);
		if (ret) {
			gsc_err("failed link flite to gsc\n");
			return ret;
		}
	}
	for (i = 0; i < num_clients; i++) {
		isp_info = pdata->isp_info[i];
		id = isp_info->cam_port;
		/* FIMC-LITE ------> GSC-SUBDEV (ITU & MIPI common) */
		source = &gsc->cap.sd_flite[id]->entity;
		sink = &gsc->cap.sd_cap->entity;
		if (source && sink) {
			if (pdata->cam_preview)
				ret = media_entity_create_link(source,
						FLITE_PAD_SOURCE_PREV,
						sink, GSC_PAD_SINK, 0);
			if (!ret && pdata->cam_camcording)
				ret = media_entity_create_link(source,
						FLITE_PAD_SOURCE_CAMCORD,
						sink, GSC_PAD_SINK, 0);
			if (ret) {
				gsc_err("failed link flite to gsc\n");
				return ret;
			}
		}
	}

	return 0;
}
Exemplo n.º 15
0
int gsc_out_link_validate(const struct media_pad *source,
			  const struct media_pad *sink)
{
	struct v4l2_subdev_format src_fmt;
	struct v4l2_subdev_crop dst_crop;
	struct v4l2_subdev *sd;
	struct gsc_dev *gsc;
	struct gsc_frame *f;
	int ret;

	if (media_entity_type(source->entity) != MEDIA_ENT_T_V4L2_SUBDEV ||
	    media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV) {
		gsc_err("media entity type isn't subdev\n");
		return 0;
	}

	sd = media_entity_to_v4l2_subdev(source->entity);
	gsc = entity_data_to_gsc(v4l2_get_subdevdata(sd));
	f = &gsc->out.ctx->d_frame;

	src_fmt.format.width = f->crop.width;
	src_fmt.format.height = f->crop.height;
	src_fmt.format.code = f->fmt->mbus_code;

	sd = media_entity_to_v4l2_subdev(sink->entity);
	/* To check if G-Scaler destination size and Mixer destinatin size
	   are the same */
	dst_crop.pad = sink->index;
	dst_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
	ret = v4l2_subdev_call(sd, pad, get_crop, NULL, &dst_crop);
	if (ret < 0 && ret != -ENOIOCTLCMD) {
		gsc_err("subdev get_fmt is failed\n");
		return -EPIPE;
	}

	if (src_fmt.format.width != dst_crop.rect.width ||
	    src_fmt.format.height != dst_crop.rect.height) {
		gsc_err("sink and source format is different\
			src_fmt.w = %d, src_fmt.h = %d,\
			dst_crop.w = %d, dst_crop.h = %d, rotation = %d",
			src_fmt.format.width, src_fmt.format.height,
			dst_crop.rect.width, dst_crop.rect.height,
			gsc->out.ctx->gsc_ctrls.rotate->val);
		return -EINVAL;
	}
Exemplo n.º 16
0
u32 get_plane_size(struct gsc_frame *frame, unsigned int plane)
{
	if (!frame || plane >= frame->fmt->num_planes) {
		gsc_err("Invalid argument");
		return 0;
	}

	return frame->payload[plane];
}
Exemplo n.º 17
0
void gsc_op_timer_handler(unsigned long arg)
{
	struct gsc_ctx *ctx = (struct gsc_ctx *)arg;
	struct gsc_dev *gsc = ctx->gsc_dev;
	struct vb2_buffer *src_vb, *dst_vb;

	clear_bit(ST_M2M_RUN, &gsc->state);
	pm_runtime_put_sync(&gsc->pdev->dev);

	src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
	dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
	if (src_vb && dst_vb) {
		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
	}
	gsc_err("GSCALER[%d] interrupt hasn't been triggered", gsc->id);
	gsc_err("erro ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
}
Exemplo n.º 18
0
static int gsc_capture_open(struct file *file)
{
	struct gsc_dev *gsc = video_drvdata(file);
	int ret = v4l2_fh_open(file);

	if (ret)
		return ret;

	if (gsc_m2m_opened(gsc) || gsc_out_opened(gsc) || gsc_cap_opened(gsc)) {
		v4l2_fh_release(file);
		return -EBUSY;
	}

	set_bit(ST_CAPT_OPEN, &gsc->state);

	pm_runtime_get_sync(&gsc->pdev->dev);

	if (++gsc->cap.refcnt == 1) {
		ret = gsc_cap_pipeline_initialize(gsc, &gsc->cap.vfd->entity, true);
		if (ret < 0) {
			gsc_err("gsc pipeline initialization failed\n");
			goto err;
		}

		ret = gsc_capture_ctrls_create(gsc);
		if (ret) {
			gsc_err("failed to create controls\n");
			goto err;
		}
	}

	gsc_dbg("pid: %d, state: 0x%lx", task_pid_nr(current), gsc->state);

	return 0;

err:
	pm_runtime_put_sync(&gsc->pdev->dev);
	v4l2_fh_release(file);
	clear_bit(ST_CAPT_OPEN, &gsc->state);
	return ret;
}
static int gsc_clk_enable_for_wb(struct gsc_dev *gsc)
{
	struct clk *gsd;
	int ret = 0;

	gsd = devm_clk_get(&gsc->pdev->dev, "gate_gsd");
	if (IS_ERR(gsd)) {
		gsc_err("fail to get gsd clock");
		return PTR_ERR(gsd);
	}

	ret = clk_prepare_enable(gsd);
	if (ret) {
		gsc_err("fail to enable gsd");
		return -EINVAL;
	}

	clk_put(gsd);

	return 0;
}
static int gsc_capture_streamon(struct file *file, void *priv,
				enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);

	if (gsc_cap_active(gsc)) {
		gsc_err("gsc didn't stop complete");
		return -EBUSY;
	}

	return vb2_streamon(&gsc->cap.vbq, type);
}
static int gsc_cap_stop_capture(struct gsc_dev *gsc)
{
	int ret;
	gsc_dbg("G-Scaler h/w disable control");
	ret = wait_event_timeout(gsc->irq_queue,
			!test_bit(ST_CAPT_RUN, &gsc->state),
			GSC_SHUTDOWN_TIMEOUT);
	if (ret == 0) {
		gsc_err("wait timeout");
		return -EBUSY;
	}

	return 0;
}
static int gsc_cap_check_limit_size(struct gsc_dev *gsc, unsigned int pad,
				   struct v4l2_mbus_framefmt *fmt)
{
	struct gsc_variant *variant = gsc->variant;
	u32 src_crop = fmt->width * fmt->height;
	u32 max_src_size =
		variant->pix_max->otf_w * variant->pix_max->otf_h;
	switch (pad) {
	case GSC_PAD_SINK:
		if (src_crop > max_src_size) {
			gsc_err("%d x %d is not supported",
					fmt->width, fmt->height);
			return -EINVAL;
		}
	break;

	default:
		gsc_err("unsupported pad");
		return -EINVAL;
	}

	return 0;
}
Exemplo n.º 23
0
static int queue_init(void *priv, struct vb2_queue *src_vq,
		      struct vb2_queue *dst_vq)
{
	struct gsc_ctx *ctx = priv;
	int ret;

	memset(src_vq, 0, sizeof(*src_vq));
	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
	src_vq->drv_priv = ctx;
	src_vq->ops = &gsc_m2m_qops;
	src_vq->mem_ops = ctx->gsc_dev->vb2->ops;
	src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);

	ret = vb2_queue_init(src_vq);
	if (ret) {
		gsc_err("failed to init vb2_queue");
		return ret;
	}

	memset(dst_vq, 0, sizeof(*dst_vq));
	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
	dst_vq->drv_priv = ctx;
	dst_vq->ops = &gsc_m2m_qops;
	dst_vq->mem_ops = ctx->gsc_dev->vb2->ops;
	dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);

	ret = vb2_queue_init(dst_vq);
	if (ret) {
		gsc_err("failed to init vb2_queue");
		return ret;
	}
	return ret;
}
static int gsc_clk_disable_for_wb(struct gsc_dev *gsc)
{
	struct clk *gsd;

	gsd = devm_clk_get(&gsc->pdev->dev, "gate_gsd");
	if (IS_ERR(gsd)) {
		gsc_err("fail to get gsd clock");
		return PTR_ERR(gsd);
	}

	clk_disable_unprepare(gsd);
	clk_put(gsd);

	return 0;
}
static int gsc_cap_set_addr(struct gsc_dev *gsc,struct gsc_ctx *ctx,
			struct gsc_input_buf *buf, int index)
{
	int ret;

	ret = gsc_prepare_addr(ctx, &buf->vb, &ctx->d_frame,
			&ctx->d_frame.addr);
	if (ret) {
		gsc_err("Prepare G-Scaler address failed\n");
		return -EINVAL;
	}

	if (!ctx->d_frame.addr.y) {
		gsc_err("source address is null");
		return -EINVAL;
	}

	buf->addr = ctx->d_frame.addr;
	list_add_tail(&buf->list, &gsc->cap.active_buf_q);
	gsc_hw_set_output_addr_fixed(gsc, &ctx->d_frame.addr);
	buf->idx = index;

	return 0;
}
Exemplo n.º 26
0
u32 get_plane_info(struct gsc_frame frm, u32 addr, u32 *index)
{
	if (frm.addr.y == addr) {
		*index = 0;
		return frm.addr.y;
	} else if (frm.addr.cb == addr) {
		*index = 1;
		return frm.addr.cb;
	} else if (frm.addr.cr == addr) {
		*index = 2;
		return frm.addr.cr;
	} else {
		gsc_err("Plane address is wrong");
		return -EINVAL;
	}
}
Exemplo n.º 27
0
int gsc_cal_prescaler_ratio(struct gsc_variant *var, u32 src, u32 dst, u32 *ratio)
{
	if ((dst > src) || (dst >= src / var->poly_sc_down_max)) {
		*ratio = 1;
		return 0;
	}

	if ((src / var->poly_sc_down_max / var->pre_sc_down_max) > dst) {
		gsc_err("scale ratio exceeded maximun scale down ratio(1/16)");
		return -EINVAL;
	}

	*ratio = (dst > (src / 8)) ? 2 : 4;

	return 0;
}
Exemplo n.º 28
0
static int gsc_capture_set_addr(struct vb2_buffer *vb)
{
	struct gsc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct gsc_dev *gsc = ctx->gsc_dev;
	int ret;

	ret = gsc_prepare_addr(ctx, vb, &ctx->d_frame, &ctx->d_frame.addr);
	if (ret) {
		gsc_err("Prepare G-Scaler address failed\n");
		return -EINVAL;
	}

	gsc_hw_set_output_addr(gsc, &ctx->d_frame.addr, vb->v4l2_buf.index);

	return 0;
}
Exemplo n.º 29
0
static int gsc_cap_register_sensor_entities(struct gsc_dev *gsc)
{
	struct exynos_platform_gscaler *pdata = gsc->pdata;
	u32 num_clients = pdata->num_clients;
	int i;

	for (i = 0; i < num_clients; i++) {
		gsc->cap.sensor[i].pdata = pdata->isp_info[i];
		gsc->cap.sensor[i].sd = gsc_cap_register_sensor(gsc, i);
		if (IS_ERR_OR_NULL(gsc->cap.sensor[i].sd)) {
			gsc_err("failed to get register sensor");
			return -EINVAL;
		}
	}

	return 0;
}
Exemplo n.º 30
0
static int gsc_m2m_s_fmt_mplane(struct file *file, void *fh,
				 struct v4l2_format *f)
{
	struct gsc_ctx *ctx = fh_to_ctx(fh);
	struct vb2_queue *vq;
	struct gsc_frame *frame;
	struct v4l2_pix_format_mplane *pix;
	int i, ret = 0;

	ret = gsc_m2m_try_fmt_mplane(file, fh, f);
	if (ret)
		return ret;

	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);

	if (vb2_is_streaming(vq)) {
		gsc_err("queue (%d) busy", f->type);
		return -EBUSY;
	}

	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
		frame = &ctx->s_frame;
	} else {
		frame = &ctx->d_frame;
	}

	pix = &f->fmt.pix_mp;
	frame->fmt = find_format(&pix->pixelformat, NULL, 0);
	if (!frame->fmt)
		return -EINVAL;

	for (i = 0; i < frame->fmt->num_planes; i++)
		frame->payload[i] = pix->plane_fmt[i].sizeimage;

	gsc_set_frame_size(frame, pix->width, pix->height);

	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		gsc_ctx_state_lock_set(GSC_PARAMS | GSC_DST_FMT, ctx);
	else
		gsc_ctx_state_lock_set(GSC_PARAMS | GSC_SRC_FMT, ctx);

	gsc_dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);

	return 0;
}