Lines Matching +full:exynos5420 +full:- +full:scaler

1 // SPDX-License-Identifier: GPL-2.0-only
24 #include "regs-scaler.h"
26 #define scaler_read(offset) readl(scaler->regs + (offset))
27 #define scaler_write(cfg, offset) writel(cfg, scaler->regs + (offset))
92 static inline int scaler_reset(struct scaler_context *scaler) in scaler_reset() argument
99 } while (--retry > 1 && in scaler_reset()
104 } while (--retry > 0 && scaler_read(SCALER_INT_EN) != 1); in scaler_reset()
106 return retry ? 0 : -EIO; in scaler_reset()
109 static inline void scaler_enable_int(struct scaler_context *scaler) in scaler_enable_int() argument
142 static inline void scaler_set_src_fmt(struct scaler_context *scaler, in scaler_set_src_fmt() argument
151 static inline void scaler_set_src_base(struct scaler_context *scaler, in scaler_set_src_base() argument
161 for (i = 0; i < src_buf->format->num_planes; ++i) in scaler_set_src_base()
162 scaler_write(src_buf->dma_addr[i], bases[i]); in scaler_set_src_base()
165 static inline void scaler_set_src_span(struct scaler_context *scaler, in scaler_set_src_span() argument
170 val = SCALER_SRC_SPAN_SET_Y_SPAN(src_buf->buf.pitch[0] / in scaler_set_src_span()
171 src_buf->format->cpp[0]); in scaler_set_src_span()
173 if (src_buf->format->num_planes > 1) in scaler_set_src_span()
174 val |= SCALER_SRC_SPAN_SET_C_SPAN(src_buf->buf.pitch[1]); in scaler_set_src_span()
179 static inline void scaler_set_src_luma_chroma_pos(struct scaler_context *scaler, in scaler_set_src_luma_chroma_pos() argument
185 val = SCALER_SRC_Y_POS_SET_YH_POS(src_pos->x << 2); in scaler_set_src_luma_chroma_pos()
186 val |= SCALER_SRC_Y_POS_SET_YV_POS(src_pos->y << 2); in scaler_set_src_luma_chroma_pos()
189 (src_pos->x * fmt->chroma_tile_w / 16) << 2); in scaler_set_src_luma_chroma_pos()
191 (src_pos->y * fmt->chroma_tile_h / 16) << 2); in scaler_set_src_luma_chroma_pos()
195 static inline void scaler_set_src_wh(struct scaler_context *scaler, in scaler_set_src_wh() argument
200 val = SCALER_SRC_WH_SET_WIDTH(src_pos->w); in scaler_set_src_wh()
201 val |= SCALER_SRC_WH_SET_HEIGHT(src_pos->h); in scaler_set_src_wh()
205 static inline void scaler_set_dst_fmt(struct scaler_context *scaler, in scaler_set_dst_fmt() argument
214 static inline void scaler_set_dst_base(struct scaler_context *scaler, in scaler_set_dst_base() argument
224 for (i = 0; i < dst_buf->format->num_planes; ++i) in scaler_set_dst_base()
225 scaler_write(dst_buf->dma_addr[i], bases[i]); in scaler_set_dst_base()
228 static inline void scaler_set_dst_span(struct scaler_context *scaler, in scaler_set_dst_span() argument
233 val = SCALER_DST_SPAN_SET_Y_SPAN(dst_buf->buf.pitch[0] / in scaler_set_dst_span()
234 dst_buf->format->cpp[0]); in scaler_set_dst_span()
236 if (dst_buf->format->num_planes > 1) in scaler_set_dst_span()
237 val |= SCALER_DST_SPAN_SET_C_SPAN(dst_buf->buf.pitch[1]); in scaler_set_dst_span()
242 static inline void scaler_set_dst_luma_pos(struct scaler_context *scaler, in scaler_set_dst_luma_pos() argument
247 val = SCALER_DST_WH_SET_WIDTH(dst_pos->w); in scaler_set_dst_luma_pos()
248 val |= SCALER_DST_WH_SET_HEIGHT(dst_pos->h); in scaler_set_dst_luma_pos()
252 static inline void scaler_set_dst_wh(struct scaler_context *scaler, in scaler_set_dst_wh() argument
257 val = SCALER_DST_POS_SET_H_POS(dst_pos->x); in scaler_set_dst_wh()
258 val |= SCALER_DST_POS_SET_V_POS(dst_pos->y); in scaler_set_dst_wh()
262 static inline void scaler_set_hv_ratio(struct scaler_context *scaler, in scaler_set_hv_ratio() argument
270 h_ratio = (src_pos->h << 16) / dst_pos->w; in scaler_set_hv_ratio()
271 v_ratio = (src_pos->w << 16) / dst_pos->h; in scaler_set_hv_ratio()
273 h_ratio = (src_pos->w << 16) / dst_pos->w; in scaler_set_hv_ratio()
274 v_ratio = (src_pos->h << 16) / dst_pos->h; in scaler_set_hv_ratio()
284 static inline void scaler_set_rotation(struct scaler_context *scaler, in scaler_set_rotation() argument
302 static inline void scaler_set_csc(struct scaler_context *scaler, in scaler_set_csc() argument
319 switch (fmt->format) { in scaler_set_csc()
340 static inline void scaler_set_timer(struct scaler_context *scaler, in scaler_set_timer() argument
351 static inline void scaler_start_hw(struct scaler_context *scaler) in scaler_start_hw() argument
359 struct scaler_context *scaler = in scaler_commit() local
362 struct drm_exynos_ipp_task_rect *src_pos = &task->src.rect; in scaler_commit()
363 struct drm_exynos_ipp_task_rect *dst_pos = &task->dst.rect; in scaler_commit()
366 src_fmt = scaler_get_format(task->src.buf.fourcc); in scaler_commit()
367 dst_fmt = scaler_get_format(task->dst.buf.fourcc); in scaler_commit()
369 pm_runtime_get_sync(scaler->dev); in scaler_commit()
370 if (scaler_reset(scaler)) { in scaler_commit()
371 pm_runtime_put(scaler->dev); in scaler_commit()
372 return -EIO; in scaler_commit()
375 scaler->task = task; in scaler_commit()
378 scaler, src_fmt->internal_fmt, task->src.buf.modifier != 0); in scaler_commit()
379 scaler_set_src_base(scaler, &task->src); in scaler_commit()
380 scaler_set_src_span(scaler, &task->src); in scaler_commit()
381 scaler_set_src_luma_chroma_pos(scaler, src_pos, src_fmt); in scaler_commit()
382 scaler_set_src_wh(scaler, src_pos); in scaler_commit()
384 scaler_set_dst_fmt(scaler, dst_fmt->internal_fmt); in scaler_commit()
385 scaler_set_dst_base(scaler, &task->dst); in scaler_commit()
386 scaler_set_dst_span(scaler, &task->dst); in scaler_commit()
387 scaler_set_dst_luma_pos(scaler, dst_pos); in scaler_commit()
388 scaler_set_dst_wh(scaler, dst_pos); in scaler_commit()
390 scaler_set_hv_ratio(scaler, task->transform.rotation, src_pos, dst_pos); in scaler_commit()
391 scaler_set_rotation(scaler, task->transform.rotation); in scaler_commit()
393 scaler_set_csc(scaler, task->src.format); in scaler_commit()
395 scaler_set_timer(scaler, 0xffff, 0xf); in scaler_commit()
397 scaler_enable_int(scaler); in scaler_commit()
398 scaler_start_hw(scaler); in scaler_commit()
407 static inline void scaler_disable_int(struct scaler_context *scaler) in scaler_disable_int() argument
412 static inline u32 scaler_get_int_status(struct scaler_context *scaler) in scaler_get_int_status() argument
423 return val & SCALER_INT_STATUS_FRAME_END ? 0 : -EINVAL; in scaler_task_done()
428 struct scaler_context *scaler = arg; in scaler_irq_handler() local
430 u32 val = scaler_get_int_status(scaler); in scaler_irq_handler()
432 scaler_disable_int(scaler); in scaler_irq_handler()
434 if (scaler->task) { in scaler_irq_handler()
435 struct exynos_drm_ipp_task *task = scaler->task; in scaler_irq_handler()
437 scaler->task = NULL; in scaler_irq_handler()
438 pm_runtime_mark_last_busy(scaler->dev); in scaler_irq_handler()
439 pm_runtime_put_autosuspend(scaler->dev); in scaler_irq_handler()
448 struct scaler_context *scaler = dev_get_drvdata(dev); in scaler_bind() local
450 struct exynos_drm_ipp *ipp = &scaler->ipp; in scaler_bind()
452 scaler->drm_dev = drm_dev; in scaler_bind()
453 ipp->drm_dev = drm_dev; in scaler_bind()
454 exynos_drm_register_dma(drm_dev, dev, &scaler->dma_priv); in scaler_bind()
459 scaler->scaler_data->formats, in scaler_bind()
460 scaler->scaler_data->num_formats, "scaler"); in scaler_bind()
462 dev_info(dev, "The exynos scaler has been probed successfully\n"); in scaler_bind()
470 struct scaler_context *scaler = dev_get_drvdata(dev); in scaler_unbind() local
471 struct exynos_drm_ipp *ipp = &scaler->ipp; in scaler_unbind()
474 exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev, in scaler_unbind()
475 &scaler->dma_priv); in scaler_unbind()
485 struct device *dev = &pdev->dev; in scaler_probe()
487 struct scaler_context *scaler; in scaler_probe() local
491 scaler = devm_kzalloc(dev, sizeof(*scaler), GFP_KERNEL); in scaler_probe()
492 if (!scaler) in scaler_probe()
493 return -ENOMEM; in scaler_probe()
495 scaler->scaler_data = in scaler_probe()
498 scaler->dev = dev; in scaler_probe()
500 scaler->regs = devm_ioremap_resource(dev, regs_res); in scaler_probe()
501 if (IS_ERR(scaler->regs)) in scaler_probe()
502 return PTR_ERR(scaler->regs); in scaler_probe()
509 IRQF_ONESHOT, "drm_scaler", scaler); in scaler_probe()
515 for (i = 0; i < scaler->scaler_data->num_clk; ++i) { in scaler_probe()
516 scaler->clock[i] = devm_clk_get(dev, in scaler_probe()
517 scaler->scaler_data->clk_name[i]); in scaler_probe()
518 if (IS_ERR(scaler->clock[i])) { in scaler_probe()
520 return PTR_ERR(scaler->clock[i]); in scaler_probe()
527 platform_set_drvdata(pdev, scaler); in scaler_probe()
543 struct device *dev = &pdev->dev; in scaler_remove()
561 static int scaler_clk_ctrl(struct scaler_context *scaler, bool enable) in scaler_clk_ctrl() argument
567 for (i = 0; i < scaler->scaler_data->num_clk; ++i) in scaler_clk_ctrl()
568 clk_fun(scaler->clock[i]); in scaler_clk_ctrl()
575 struct scaler_context *scaler = dev_get_drvdata(dev); in scaler_runtime_suspend() local
577 return scaler_clk_ctrl(scaler, false); in scaler_runtime_suspend()
582 struct scaler_context *scaler = dev_get_drvdata(dev); in scaler_runtime_resume() local
584 return scaler_clk_ctrl(scaler, true); in scaler_runtime_resume()
717 .compatible = "samsung,exynos5420-scaler",
720 .compatible = "samsung,exynos5433-scaler",
731 .name = "exynos-scaler",