Lines Matching +full:exynos4212 +full:- +full:fimc

1 // SPDX-License-Identifier: GPL-2.0-or-later
26 #include "regs-fimc.h"
29 * FIMC stands for Fully Interactive Mobile Camera and
33 * FIMC supports image rotation and image effect functions.
47 MODULE_PARM_DESC(fimc_devs, "Alias mask for assigning FIMC devices to Exynos DRM");
61 [FIMC_CLK_GATE] = "fimc",
86 * A structure of fimc context.
90 * @clocks: fimc clocks.
93 * @id: fimc id.
115 return readl(ctx->regs + reg); in fimc_read()
120 writel(val, ctx->regs + reg); in fimc_write()
125 void __iomem *r = ctx->regs + reg; in fimc_set_bits()
132 void __iomem *r = ctx->regs + reg; in fimc_clear_bits()
186 DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable); in fimc_handle_jpeg()
201 DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable); in fimc_mask_irq()
225 DRM_DEV_DEBUG_KMS(ctx->dev, "flag[0x%x]\n", flag); in fimc_check_ovf()
232 DRM_DEV_ERROR(ctx->dev, in fimc_check_ovf()
234 ctx->id, status); in fimc_check_ovf()
247 DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]\n", cfg); in fimc_check_frame_end()
269 DRM_DEV_DEBUG_KMS(ctx->dev, "present[%d]before[%d]\n", in fimc_get_buf_id()
274 DRM_DEV_ERROR(ctx->dev, "failed to get frame count.\n"); in fimc_get_buf_id()
275 return -EIO; in fimc_get_buf_id()
278 buf_id = frame_cnt - 1; in fimc_get_buf_id()
279 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id); in fimc_get_buf_id()
288 DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable); in fimc_handle_lastend()
303 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); in fimc_src_set_fmt_order()
368 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); in fimc_src_set_fmt()
421 DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[%x]\n", rotation); in fimc_src_set_transf()
470 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; in fimc_set_window()
474 h1 = buf->rect.x; in fimc_set_window()
475 h2 = real_width - buf->rect.w - buf->rect.x; in fimc_set_window()
476 v1 = buf->rect.y; in fimc_set_window()
477 v2 = buf->buf.height - buf->rect.h - buf->rect.y; in fimc_set_window()
479 DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n", in fimc_set_window()
480 buf->rect.x, buf->rect.y, buf->rect.w, buf->rect.h, in fimc_set_window()
481 real_width, buf->buf.height); in fimc_set_window()
482 DRM_DEV_DEBUG_KMS(ctx->dev, "h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, in fimc_set_window()
487 * check figure 43-21 in user manual in fimc_set_window()
505 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; in fimc_src_set_size()
508 DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width, in fimc_src_set_size()
509 buf->buf.height); in fimc_src_set_size()
513 EXYNOS_ORGISIZE_VERTICAL(buf->buf.height)); in fimc_src_set_size()
517 DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, in fimc_src_set_size()
518 buf->rect.y, buf->rect.w, buf->rect.h); in fimc_src_set_size()
524 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(buf->rect.w) | in fimc_src_set_size()
525 EXYNOS_CIREAL_ISIZE_HEIGHT(buf->rect.h)); in fimc_src_set_size()
534 EXYNOS_CISRCFMT_SOURCEVSIZE(buf->buf.height)); in fimc_src_set_size()
538 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(buf->rect.x) | in fimc_src_set_size()
539 EXYNOS_CIIYOFF_VERTICAL(buf->rect.y)); in fimc_src_set_size()
541 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(buf->rect.x) | in fimc_src_set_size()
542 EXYNOS_CIICBOFF_VERTICAL(buf->rect.y)); in fimc_src_set_size()
544 cfg = (EXYNOS_CIICROFF_HORIZONTAL(buf->rect.x) | in fimc_src_set_size()
545 EXYNOS_CIICROFF_VERTICAL(buf->rect.y)); in fimc_src_set_size()
554 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIIYSA(0)); in fimc_src_set_addr()
555 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIICBSA(0)); in fimc_src_set_addr()
556 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIICRSA(0)); in fimc_src_set_addr()
563 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); in fimc_dst_set_fmt_order()
634 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); in fimc_dst_set_fmt()
694 DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[0x%x]\n", rotation); in fimc_dst_set_transf()
748 src_w = src->h; in fimc_set_prescaler()
749 src_h = src->w; in fimc_set_prescaler()
751 src_w = src->w; in fimc_set_prescaler()
752 src_h = src->h; in fimc_set_prescaler()
756 dst_w = dst->h; in fimc_set_prescaler()
757 dst_h = dst->w; in fimc_set_prescaler()
759 dst_w = dst->w; in fimc_set_prescaler()
760 dst_h = dst->h; in fimc_set_prescaler()
766 dev_err(ctx->dev, "failed to get ratio horizontal.\n"); in fimc_set_prescaler()
767 return -EINVAL; in fimc_set_prescaler()
772 dev_err(ctx->dev, "failed to get ratio vertical.\n"); in fimc_set_prescaler()
773 return -EINVAL; in fimc_set_prescaler()
778 DRM_DEV_DEBUG_KMS(ctx->dev, "pre_dst_width[%d]pre_dst_height[%d]\n", in fimc_set_prescaler()
780 DRM_DEV_DEBUG_KMS(ctx->dev, "hfactor[%d]vfactor[%d]\n", hfactor, in fimc_set_prescaler()
783 sc->hratio = (src_w << 14) / (dst_w << hfactor); in fimc_set_prescaler()
784 sc->vratio = (src_h << 14) / (dst_h << vfactor); in fimc_set_prescaler()
785 sc->up_h = (dst_w >= src_w); in fimc_set_prescaler()
786 sc->up_v = (dst_h >= src_h); in fimc_set_prescaler()
787 DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n", in fimc_set_prescaler()
788 sc->hratio, sc->vratio, sc->up_h, sc->up_v); in fimc_set_prescaler()
790 shfactor = FIMC_SHFACTOR - (hfactor + vfactor); in fimc_set_prescaler()
791 DRM_DEV_DEBUG_KMS(ctx->dev, "shfactor[%d]\n", shfactor); in fimc_set_prescaler()
809 DRM_DEV_DEBUG_KMS(ctx->dev, "range[%d]bypass[%d]up_h[%d]up_v[%d]\n", in fimc_set_scaler()
810 sc->range, sc->bypass, sc->up_h, sc->up_v); in fimc_set_scaler()
811 DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]\n", in fimc_set_scaler()
812 sc->hratio, sc->vratio); in fimc_set_scaler()
822 if (sc->range) in fimc_set_scaler()
825 if (sc->bypass) in fimc_set_scaler()
827 if (sc->up_h) in fimc_set_scaler()
829 if (sc->up_v) in fimc_set_scaler()
832 cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) | in fimc_set_scaler()
833 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6))); in fimc_set_scaler()
839 cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) | in fimc_set_scaler()
840 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio)); in fimc_set_scaler()
847 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; in fimc_dst_set_size()
850 DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width, in fimc_dst_set_size()
851 buf->buf.height); in fimc_dst_set_size()
855 EXYNOS_ORGOSIZE_VERTICAL(buf->buf.height)); in fimc_dst_set_size()
859 DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, in fimc_dst_set_size()
860 buf->rect.y, in fimc_dst_set_size()
861 buf->rect.w, buf->rect.h); in fimc_dst_set_size()
867 if (buf->buf.width >= FIMC_WIDTH_ITU_709) in fimc_dst_set_size()
881 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.h) | in fimc_dst_set_size()
882 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.w)); in fimc_dst_set_size()
884 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.w) | in fimc_dst_set_size()
885 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.h)); in fimc_dst_set_size()
889 cfg = EXYNOS_CITAREA_TARGET_AREA(buf->rect.w * buf->rect.h); in fimc_dst_set_size()
893 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(buf->rect.x) | in fimc_dst_set_size()
894 EXYNOS_CIOYOFF_VERTICAL(buf->rect.y)); in fimc_dst_set_size()
896 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(buf->rect.x) | in fimc_dst_set_size()
897 EXYNOS_CIOCBOFF_VERTICAL(buf->rect.y)); in fimc_dst_set_size()
899 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(buf->rect.x) | in fimc_dst_set_size()
900 EXYNOS_CIOCROFF_VERTICAL(buf->rect.y)); in fimc_dst_set_size()
911 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]enqueu[%d]\n", buf_id, enqueue); in fimc_dst_set_buf_seq()
913 spin_lock_irqsave(&ctx->lock, flags); in fimc_dst_set_buf_seq()
931 spin_unlock_irqrestore(&ctx->lock, flags); in fimc_dst_set_buf_seq()
937 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIOYSA(0)); in fimc_dst_set_addr()
938 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIOCBSA(0)); in fimc_dst_set_addr()
939 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIOCRSA(0)); in fimc_dst_set_addr()
951 DRM_DEV_DEBUG_KMS(ctx->dev, "fimc id[%d]\n", ctx->id); in fimc_irq_handler()
964 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id); in fimc_irq_handler()
966 if (ctx->task) { in fimc_irq_handler()
967 struct exynos_drm_ipp_task *task = ctx->task; in fimc_irq_handler()
969 ctx->task = NULL; in fimc_irq_handler()
970 pm_runtime_mark_last_busy(ctx->dev); in fimc_irq_handler()
971 pm_runtime_put_autosuspend(ctx->dev); in fimc_irq_handler()
1004 memset(&ctx->sc, 0x0, sizeof(ctx->sc)); in fimc_reset()
1017 fimc_set_scaler(ctx, &ctx->sc); in fimc_start()
1088 ret = pm_runtime_resume_and_get(ctx->dev); in fimc_commit()
1090 dev_err(ctx->dev, "failed to enable FIMC device.\n"); in fimc_commit()
1094 ctx->task = task; in fimc_commit()
1096 fimc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier); in fimc_commit()
1097 fimc_src_set_size(ctx, &task->src); in fimc_commit()
1099 fimc_src_set_addr(ctx, &task->src); in fimc_commit()
1100 fimc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier); in fimc_commit()
1101 fimc_dst_set_transf(ctx, task->transform.rotation); in fimc_commit()
1102 fimc_dst_set_size(ctx, &task->dst); in fimc_commit()
1103 fimc_dst_set_addr(ctx, &task->dst); in fimc_commit()
1104 fimc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect); in fimc_commit()
1118 if (ctx->task) { in fimc_abort()
1119 struct exynos_drm_ipp_task *task = ctx->task; in fimc_abort()
1121 ctx->task = NULL; in fimc_abort()
1122 pm_runtime_mark_last_busy(ctx->dev); in fimc_abort()
1123 pm_runtime_put_autosuspend(ctx->dev); in fimc_abort()
1124 exynos_drm_ipp_task_done(task, -EIO); in fimc_abort()
1137 struct exynos_drm_ipp *ipp = &ctx->ipp; in fimc_bind()
1139 ctx->drm_dev = drm_dev; in fimc_bind()
1140 ipp->drm_dev = drm_dev; in fimc_bind()
1141 exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); in fimc_bind()
1146 ctx->formats, ctx->num_formats, "fimc"); in fimc_bind()
1148 dev_info(dev, "The exynos fimc has been probed successfully\n"); in fimc_bind()
1158 struct exynos_drm_ipp *ipp = &ctx->ipp; in fimc_unbind()
1161 exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv); in fimc_unbind()
1174 if (IS_ERR(ctx->clocks[i])) in fimc_put_clocks()
1176 clk_put(ctx->clocks[i]); in fimc_put_clocks()
1177 ctx->clocks[i] = ERR_PTR(-EINVAL); in fimc_put_clocks()
1183 struct device *fimc_dev = ctx->dev; in fimc_setup_clocks()
1188 ctx->clocks[i] = ERR_PTR(-EINVAL); in fimc_setup_clocks()
1192 dev = fimc_dev->parent; in fimc_setup_clocks()
1196 ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]); in fimc_setup_clocks()
1197 if (IS_ERR(ctx->clocks[i])) { in fimc_setup_clocks()
1198 ret = PTR_ERR(ctx->clocks[i]); in fimc_setup_clocks()
1205 ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]); in fimc_setup_clocks()
1215 int id = of_alias_get_id(dev->of_node, "fimc"); in exynos_drm_check_fimc_device()
1219 return -ENODEV; in exynos_drm_check_fimc_device()
1268 struct device *dev = &pdev->dev; in fimc_probe()
1274 return -ENODEV; in fimc_probe()
1278 return -ENOMEM; in fimc_probe()
1280 ctx->dev = dev; in fimc_probe()
1281 ctx->id = of_alias_get_id(dev->of_node, "fimc"); in fimc_probe()
1288 return -ENOMEM; in fimc_probe()
1291 if (ctx->id < 3) { in fimc_probe()
1307 if (ctx->id < 3) { in fimc_probe()
1323 ctx->formats = formats; in fimc_probe()
1324 ctx->num_formats = num_formats; in fimc_probe()
1327 ctx->regs = devm_platform_ioremap_resource(pdev, 0); in fimc_probe()
1328 if (IS_ERR(ctx->regs)) in fimc_probe()
1329 return PTR_ERR(ctx->regs); in fimc_probe()
1347 spin_lock_init(&ctx->lock); in fimc_probe()
1358 dev_info(dev, "drm fimc registered successfully.\n"); in fimc_probe()
1372 struct device *dev = &pdev->dev; in fimc_remove()
1386 DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); in fimc_runtime_suspend()
1387 clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]); in fimc_runtime_suspend()
1395 DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); in fimc_runtime_resume()
1396 return clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]); in fimc_runtime_resume()
1403 { .compatible = "samsung,exynos4210-fimc" },
1404 { .compatible = "samsung,exynos4212-fimc" },
1414 .name = "exynos-drm-fimc",