Lines Matching +full:camerrx +full:- +full:control
1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI Camera Access Layer (CAL) - Driver
5 * Copyright (c) 2015-2020 Texas Instruments Inc.
23 #include <media/media-device.h>
24 #include <media/v4l2-async.h>
25 #include <media/v4l2-common.h>
26 #include <media/v4l2-device.h>
27 #include <media/videobuf2-core.h>
28 #include <media/videobuf2-dma-contig.h>
38 int cal_video_nr = -1;
40 MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
56 /* ------------------------------------------------------------------
58 * ------------------------------------------------------------------
159 /* ------------------------------------------------------------------
161 * ------------------------------------------------------------------
238 /* ------------------------------------------------------------------
240 * ------------------------------------------------------------------
247 cal_info(cal, "CAL Registers @ 0x%pa:\n", &cal->res->start);
249 (__force const void *)cal->base,
250 resource_size(cal->res), false);
252 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
253 struct cal_camerarx *phy = cal->phy[i];
256 &phy->res->start);
258 (__force const void *)phy->base,
259 resource_size(phy->res),
264 /* ------------------------------------------------------------------
266 * ------------------------------------------------------------------
275 spin_lock(&cal->v4l2_dev.lock);
277 ret = find_first_zero_bit(&cal->reserved_pix_proc_mask, CAL_MAX_PIX_PROC);
280 spin_unlock(&cal->v4l2_dev.lock);
281 return -ENOSPC;
284 cal->reserved_pix_proc_mask |= BIT(ret);
286 spin_unlock(&cal->v4l2_dev.lock);
293 spin_lock(&cal->v4l2_dev.lock);
295 cal->reserved_pix_proc_mask &= ~BIT(pix_proc_num);
297 spin_unlock(&cal->v4l2_dev.lock);
304 val = cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx));
305 cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK);
307 * DT type: MIPI CSI-2 Specs
308 * 0x1: All - DT filter is disabled
314 cal_set_field(&val, ctx->datatype, CAL_CSI2_CTX_DT_MASK);
315 cal_set_field(&val, ctx->vc, CAL_CSI2_CTX_VC_MASK);
316 cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
320 cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), val);
322 ctx->phy->instance, ctx->csi2_ctx,
323 cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx)));
330 switch (ctx->fmtinfo->bpp) {
357 dev_warn_once(ctx->cal->dev,
359 __FILE__, __LINE__, __func__, ctx->fmtinfo->bpp);
365 val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc));
370 cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK);
372 cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), val);
373 ctx_dbg(3, ctx, "CAL_PIX_PROC(%u) = 0x%08x\n", ctx->pix_proc,
374 cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc)));
379 unsigned int stride = ctx->v_fmt.fmt.pix.bytesperline;
382 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
383 cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK);
384 cal_set_field(&val, ctx->v_fmt.fmt.pix.height,
391 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
392 ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->dma_ctx,
393 cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)));
395 cal_write_field(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx),
397 ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->dma_ctx,
398 cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx)));
400 val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx));
404 * The XSIZE field is expressed in 64-bit units and prevents overflows
409 cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx), val);
410 ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->dma_ctx,
411 cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx)));
416 cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->dma_ctx), addr);
421 u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
425 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
430 u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
434 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
441 spin_lock_irq(&ctx->dma.lock);
442 stopped = ctx->dma.state == CAL_DMA_STOPPED;
443 spin_unlock_irq(&ctx->dma.lock);
456 phy_source_pad = media_pad_remote_pad_first(&ctx->pad);
458 return -ENODEV;
460 ret = v4l2_subdev_call(&ctx->phy->subdev, pad, get_frame_desc,
461 phy_source_pad->index, &fd);
466 return -EINVAL;
480 if (ret == -ENOIOCTLCMD) {
481 ctx->vc = 0;
482 ctx->datatype = CAL_CSI2_CTX_DT_ANY;
488 ctx->vc = entry.bus.csi2.vc;
489 ctx->datatype = entry.bus.csi2.dt;
494 ctx->use_pix_proc = ctx->vb_vidq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE;
496 if (ctx->use_pix_proc) {
497 ret = cal_reserve_pix_proc(ctx->cal);
503 ctx->pix_proc = ret;
511 if (ctx->use_pix_proc)
512 cal_release_pix_proc(ctx->cal, ctx->pix_proc);
517 struct cal_camerarx *phy = ctx->phy;
524 spin_lock(&phy->vc_lock);
526 if (phy->vc_enable_count[ctx->vc]++ == 0) {
527 phy->vc_frame_number[ctx->vc] = 0;
528 phy->vc_sequence[ctx->vc] = 0;
531 spin_unlock(&phy->vc_lock);
533 ctx->dma.state = CAL_DMA_RUNNING;
535 /* Configure the CSI-2, pixel processing and write DMA contexts. */
537 if (ctx->use_pix_proc)
542 cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(1),
543 CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
544 cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(2),
545 CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
552 struct cal_camerarx *phy = ctx->phy;
555 WARN_ON(phy->vc_enable_count[ctx->vc] == 0);
557 spin_lock(&phy->vc_lock);
558 phy->vc_enable_count[ctx->vc]--;
559 spin_unlock(&phy->vc_lock);
565 spin_lock_irq(&ctx->dma.lock);
566 ctx->dma.state = CAL_DMA_STOP_REQUESTED;
567 spin_unlock_irq(&ctx->dma.lock);
569 time_left = wait_event_timeout(ctx->dma.wait, cal_ctx_wr_dma_stopped(ctx),
577 cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(1),
578 CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
579 cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(2),
580 CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
582 ctx->dma.state = CAL_DMA_STOPPED;
585 cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), 0);
588 if (ctx->use_pix_proc)
589 cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), 0);
592 /* ------------------------------------------------------------------
594 * ------------------------------------------------------------------
600 * CSI-2 frame number as a base.
604 struct cal_dev *cal = ctx->cal;
605 struct cal_camerarx *phy = ctx->phy;
607 u8 vc = ctx->vc;
610 cal_read(cal, CAL_CSI2_STATUS(phy->instance, ctx->csi2_ctx)) &
613 if (phy->vc_frame_number[vc] != frame_num) {
614 prev_frame_num = phy->vc_frame_number[vc];
617 phy->vc_sequence[vc] += 1;
619 phy->vc_sequence[vc] += frame_num - prev_frame_num;
621 phy->vc_frame_number[vc] = frame_num;
627 spin_lock(&ctx->dma.lock);
629 if (ctx->dma.state == CAL_DMA_STOP_REQUESTED) {
636 ctx->dma.state = CAL_DMA_STOP_PENDING;
637 } else if (!list_empty(&ctx->dma.queue) && !ctx->dma.pending) {
645 buf = list_first_entry(&ctx->dma.queue, struct cal_buffer,
647 addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
650 ctx->dma.pending = buf;
651 list_del(&buf->list);
654 spin_unlock(&ctx->dma.lock);
663 spin_lock(&ctx->dma.lock);
666 if (ctx->dma.state == CAL_DMA_STOP_PENDING) {
667 ctx->dma.state = CAL_DMA_STOPPED;
668 wake_up(&ctx->dma.wait);
672 if (ctx->dma.pending) {
673 buf = ctx->dma.active;
674 ctx->dma.active = ctx->dma.pending;
675 ctx->dma.pending = NULL;
678 spin_unlock(&ctx->dma.lock);
681 buf->vb.vb2_buf.timestamp = ktime_get_ns();
682 buf->vb.field = ctx->v_fmt.fmt.pix.field;
683 buf->vb.sequence = ctx->phy->vc_sequence[ctx->vc];
685 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
706 if (ctx->v_fmt.fmt.pix.height < 10) {
735 dev_err_ratelimited(cal->dev, "OCPO ERROR\n");
737 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
742 dev_err_ratelimited(cal->dev,
752 dev_err_ratelimited(cal->dev,
761 for (i = 0; i < cal->num_contexts; ++i) {
766 cal_irq_handle_wdma(cal->ctx[i], start, end);
772 /* ------------------------------------------------------------------
774 * ------------------------------------------------------------------
792 struct cal_camerarx *phy = to_cal_asd(asd)->phy;
796 if (phy->source) {
798 subdev->name);
802 phy_dbg(1, phy, "Using source %s for capture\n", subdev->name);
804 pad = media_entity_get_fwnode_pad(&subdev->entity,
805 of_fwnode_handle(phy->source_ep_node),
809 subdev->name);
813 ret = media_create_pad_link(&subdev->entity, pad,
814 &phy->subdev.entity, CAL_CAMERARX_PAD_SINK,
819 subdev->name);
823 phy->source = subdev;
824 phy->source_pad = pad;
835 for (i = 0; i < cal->num_contexts; ++i) {
836 ret = cal_ctx_v4l2_register(cal->ctx[i]);
844 ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev);
851 for (; i > 0; --i) {
852 if (!cal->ctx[i - 1])
855 cal_ctx_v4l2_unregister(cal->ctx[i - 1]);
871 v4l2_async_nf_init(&cal->notifier, &cal->v4l2_dev);
872 cal->notifier.ops = &cal_async_notifier_ops;
874 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
875 struct cal_camerarx *phy = cal->phy[i];
879 if (!phy->source_node)
882 fwnode = of_fwnode_handle(phy->source_node);
883 casd = v4l2_async_nf_add_fwnode(&cal->notifier,
892 casd->phy = phy;
895 ret = v4l2_async_nf_register(&cal->notifier);
904 v4l2_async_nf_cleanup(&cal->notifier);
910 v4l2_async_nf_unregister(&cal->notifier);
911 v4l2_async_nf_cleanup(&cal->notifier);
914 /* ------------------------------------------------------------------
916 * ------------------------------------------------------------------
920 * Register user-facing devices. To be called at the end of the probe function
927 ret = media_device_register(&cal->mdev);
939 media_device_unregister(&cal->mdev);
947 * Unregister the user-facing devices, but don't free memory yet. To be called
955 for (i = 0; i < cal->num_contexts; i++)
956 cal_ctx_v4l2_unregister(cal->ctx[i]);
959 media_device_unregister(&cal->mdev);
963 * Initialize the in-kernel objects. To be called at the beginning of the probe
968 struct media_device *mdev = &cal->mdev;
971 mdev->dev = cal->dev;
972 mdev->hw_revision = cal->revision;
973 strscpy(mdev->model, "CAL", sizeof(mdev->model));
980 cal->v4l2_dev.mdev = mdev;
981 ret = v4l2_device_register(cal->dev, &cal->v4l2_dev);
987 vb2_dma_contig_set_max_seg_size(cal->dev, DMA_BIT_MASK(32));
993 * Cleanup the in-kernel objects, freeing memory. To be called at the very end
999 v4l2_device_unregister(&cal->v4l2_dev);
1000 media_device_cleanup(&cal->mdev);
1002 vb2_dma_contig_clear_max_seg_size(cal->dev);
1005 /* ------------------------------------------------------------------
1007 * ------------------------------------------------------------------
1019 ctx->cal = cal;
1020 ctx->dma_ctx = inst;
1021 ctx->csi2_ctx = inst;
1022 ctx->cport = inst;
1042 .compatible = "ti,dra72-cal",
1046 .compatible = "ti,dra72-pre-es2-cal",
1050 .compatible = "ti,dra76-cal",
1054 .compatible = "ti,am654-cal",
1069 cal->revision = cal_read(cal, CAL_HL_REVISION);
1070 switch (FIELD_GET(CAL_HL_REVISION_SCHEME_MASK, cal->revision)) {
1073 FIELD_GET(CAL_HL_REVISION_MAJOR_MASK, cal->revision),
1074 FIELD_GET(CAL_HL_REVISION_MINOR_MASK, cal->revision),
1075 FIELD_GET(CAL_HL_REVISION_RTL_MASK, cal->revision),
1076 cal->revision);
1082 cal->revision);
1094 struct platform_device *pdev = to_platform_device(cal->dev);
1095 struct device_node *np = cal->dev->of_node;
1102 syscon = syscon_regmap_lookup_by_phandle_args(np, "ti,camerrx-control",
1105 cal->syscon_camerrx = syscon;
1106 cal->syscon_camerrx_offset = offset;
1110 dev_warn(cal->dev, "failed to get ti,camerrx-control: %ld\n",
1119 base = devm_ioremap_resource(cal->dev, res);
1125 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
1126 res->name, &res->start, &res->end);
1131 config.max_register = resource_size(res) - 4;
1143 cal->syscon_camerrx = syscon;
1144 cal->syscon_camerrx_offset = 0;
1157 cal = devm_kzalloc(&pdev->dev, sizeof(*cal), GFP_KERNEL);
1159 return -ENOMEM;
1161 cal->data = of_device_get_match_data(&pdev->dev);
1162 if (!cal->data) {
1163 dev_err(&pdev->dev, "Could not get feature data based on compatible version\n");
1164 return -ENODEV;
1167 cal->dev = &pdev->dev;
1171 cal->fclk = devm_clk_get(&pdev->dev, "fck");
1172 if (IS_ERR(cal->fclk)) {
1173 dev_err(&pdev->dev, "cannot get CAL fclk\n");
1174 return PTR_ERR(cal->fclk);
1181 cal->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1183 cal->base = devm_ioremap_resource(&pdev->dev, cal->res);
1184 if (IS_ERR(cal->base))
1185 return PTR_ERR(cal->base);
1187 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
1188 cal->res->name, &cal->res->start, &cal->res->end);
1192 ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME,
1198 pm_runtime_enable(&pdev->dev);
1199 ret = pm_runtime_resume_and_get(&pdev->dev);
1204 pm_runtime_put_sync(&pdev->dev);
1212 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
1213 cal->phy[i] = cal_camerarx_create(cal, i);
1214 if (IS_ERR(cal->phy[i])) {
1215 ret = PTR_ERR(cal->phy[i]);
1216 cal->phy[i] = NULL;
1220 if (cal->phy[i]->source_node)
1226 ret = -ENODEV;
1232 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
1235 if (!cal->phy[i]->source_node)
1240 cal_err(cal, "Failed to create context %u\n", cal->num_contexts);
1241 ret = -ENODEV;
1245 ctx->phy = cal->phy[i];
1247 cal->ctx[cal->num_contexts++] = ctx;
1250 for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
1256 ret = -ENODEV;
1260 cal->ctx[cal->num_contexts++] = ctx;
1272 for (i = 0; i < cal->num_contexts; i++)
1273 cal_ctx_destroy(cal->ctx[i]);
1276 for (i = 0; i < cal->data->num_csi2_phy; i++)
1277 cal_camerarx_destroy(cal->phy[i]);
1282 pm_runtime_disable(&pdev->dev);
1295 ret = pm_runtime_resume_and_get(&pdev->dev);
1299 for (i = 0; i < cal->data->num_csi2_phy; i++)
1300 cal_camerarx_disable(cal->phy[i]);
1302 for (i = 0; i < cal->num_contexts; i++)
1303 cal_ctx_destroy(cal->ctx[i]);
1305 for (i = 0; i < cal->data->num_csi2_phy; i++)
1306 cal_camerarx_destroy(cal->phy[i]);
1311 pm_runtime_put_sync(&pdev->dev);
1312 pm_runtime_disable(&pdev->dev);
1321 if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
1323 * Apply errata on both port everytime we (re-)enable
1326 for (i = 0; i < cal->data->num_csi2_phy; i++)
1327 cal_camerarx_i913_errata(cal->phy[i]);