Lines Matching full:ipu

3 // Ingenic JZ47xx IPU driver
9 #include "ingenic-ipu.h"
40 void (*set_coefs)(struct ingenic_ipu *ipu, unsigned int reg,
116 static void jz4760_set_coefs(struct ingenic_ipu *ipu, unsigned int reg, in jz4760_set_coefs() argument
160 regmap_write(ipu->map, reg, val); in jz4760_set_coefs()
165 regmap_write(ipu->map, reg, val); in jz4760_set_coefs()
168 static void jz4725b_set_coefs(struct ingenic_ipu *ipu, unsigned int reg, in jz4725b_set_coefs() argument
184 regmap_write(ipu->map, reg, val); in jz4725b_set_coefs()
188 regmap_write(ipu->map, reg, JZ4725B_IPU_RSZ_LUT_IN_EN); in jz4725b_set_coefs()
192 static void ingenic_ipu_set_downscale_coefs(struct ingenic_ipu *ipu, in ingenic_ipu_set_downscale_coefs() argument
205 ipu->soc_info->set_coefs(ipu, reg, ipu->sharpness, in ingenic_ipu_set_downscale_coefs()
210 static void ingenic_ipu_set_integer_upscale_coefs(struct ingenic_ipu *ipu, in ingenic_ipu_set_integer_upscale_coefs() argument
221 ipu->soc_info->set_coefs(ipu, reg, 0, false, 512, i == num - 1); in ingenic_ipu_set_integer_upscale_coefs()
224 static void ingenic_ipu_set_upscale_coefs(struct ingenic_ipu *ipu, in ingenic_ipu_set_upscale_coefs() argument
239 ipu->soc_info->set_coefs(ipu, reg, ipu->sharpness, in ingenic_ipu_set_upscale_coefs()
244 static void ingenic_ipu_set_coefs(struct ingenic_ipu *ipu, unsigned int reg, in ingenic_ipu_set_coefs() argument
248 regmap_write(ipu->map, reg, -1); in ingenic_ipu_set_coefs()
251 ingenic_ipu_set_downscale_coefs(ipu, reg, num, denom); in ingenic_ipu_set_coefs()
253 ingenic_ipu_set_integer_upscale_coefs(ipu, reg, num); in ingenic_ipu_set_coefs()
255 ingenic_ipu_set_upscale_coefs(ipu, reg, num, denom); in ingenic_ipu_set_coefs()
287 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_update() local
299 if (!ipu->clk_enabled) { in ingenic_ipu_plane_atomic_update()
300 err = clk_enable(ipu->clk); in ingenic_ipu_plane_atomic_update()
302 dev_err(ipu->dev, "Unable to enable clock: %d\n", err); in ingenic_ipu_plane_atomic_update()
306 ipu->clk_enabled = true; in ingenic_ipu_plane_atomic_update()
312 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_RST); in ingenic_ipu_plane_atomic_update()
315 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, in ingenic_ipu_plane_atomic_update()
320 ipu->addr_y = drm_fb_cma_get_gem_addr(state->fb, state, 0); in ingenic_ipu_plane_atomic_update()
322 ipu->addr_u = drm_fb_cma_get_gem_addr(state->fb, state, 1); in ingenic_ipu_plane_atomic_update()
324 ipu->addr_v = drm_fb_cma_get_gem_addr(state->fb, state, 2); in ingenic_ipu_plane_atomic_update()
330 regmap_write(ipu->map, JZ_REG_IPU_Y_ADDR, ipu->addr_y); in ingenic_ipu_plane_atomic_update()
331 regmap_write(ipu->map, JZ_REG_IPU_U_ADDR, ipu->addr_u); in ingenic_ipu_plane_atomic_update()
332 regmap_write(ipu->map, JZ_REG_IPU_V_ADDR, ipu->addr_v); in ingenic_ipu_plane_atomic_update()
335 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_SPKG_SEL); in ingenic_ipu_plane_atomic_update()
337 ingenic_drm_plane_config(ipu->master, plane, DRM_FORMAT_XRGB8888); in ingenic_ipu_plane_atomic_update()
348 regmap_write(ipu->map, JZ_REG_IPU_UV_STRIDE, stride); in ingenic_ipu_plane_atomic_update()
351 regmap_write(ipu->map, JZ_REG_IPU_Y_STRIDE, stride); in ingenic_ipu_plane_atomic_update()
353 regmap_write(ipu->map, JZ_REG_IPU_IN_GS, in ingenic_ipu_plane_atomic_update()
420 regmap_write(ipu->map, JZ_REG_IPU_D_FMT, format); in ingenic_ipu_plane_atomic_update()
423 regmap_write(ipu->map, JZ_REG_IPU_OUT_GS, in ingenic_ipu_plane_atomic_update()
426 regmap_write(ipu->map, JZ_REG_IPU_OUT_STRIDE, state->crtc_w * 4); in ingenic_ipu_plane_atomic_update()
429 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_CSC_EN); in ingenic_ipu_plane_atomic_update()
437 regmap_write(ipu->map, JZ_REG_IPU_CSC_OFFSET, in ingenic_ipu_plane_atomic_update()
447 regmap_write(ipu->map, JZ_REG_IPU_CSC_C0_COEF, 0x4a8); in ingenic_ipu_plane_atomic_update()
448 regmap_write(ipu->map, JZ_REG_IPU_CSC_C1_COEF, 0x662); in ingenic_ipu_plane_atomic_update()
449 regmap_write(ipu->map, JZ_REG_IPU_CSC_C2_COEF, 0x191); in ingenic_ipu_plane_atomic_update()
450 regmap_write(ipu->map, JZ_REG_IPU_CSC_C3_COEF, 0x341); in ingenic_ipu_plane_atomic_update()
451 regmap_write(ipu->map, JZ_REG_IPU_CSC_C4_COEF, 0x811); in ingenic_ipu_plane_atomic_update()
458 * If the IPU supports bicubic, we enable it unconditionally, since it in ingenic_ipu_plane_atomic_update()
461 if (ipu->soc_info->has_bicubic) in ingenic_ipu_plane_atomic_update()
464 upscaling_w = ipu->num_w > ipu->denom_w; in ingenic_ipu_plane_atomic_update()
468 if (ipu->num_w != 1 || ipu->denom_w != 1) { in ingenic_ipu_plane_atomic_update()
469 if (!ipu->soc_info->has_bicubic && !upscaling_w) in ingenic_ipu_plane_atomic_update()
470 coef_index |= (ipu->denom_w - 1) << 16; in ingenic_ipu_plane_atomic_update()
472 coef_index |= (ipu->num_w - 1) << 16; in ingenic_ipu_plane_atomic_update()
476 upscaling_h = ipu->num_h > ipu->denom_h; in ingenic_ipu_plane_atomic_update()
480 if (ipu->num_h != 1 || ipu->denom_h != 1) { in ingenic_ipu_plane_atomic_update()
481 if (!ipu->soc_info->has_bicubic && !upscaling_h) in ingenic_ipu_plane_atomic_update()
482 coef_index |= ipu->denom_h - 1; in ingenic_ipu_plane_atomic_update()
484 coef_index |= ipu->num_h - 1; in ingenic_ipu_plane_atomic_update()
488 regmap_update_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_ZOOM_SEL | in ingenic_ipu_plane_atomic_update()
493 regmap_write(ipu->map, JZ_REG_IPU_RSZ_COEF_INDEX, coef_index); in ingenic_ipu_plane_atomic_update()
495 if (ipu->num_w != 1 || ipu->denom_w != 1) in ingenic_ipu_plane_atomic_update()
496 ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_HRSZ_COEF_LUT, in ingenic_ipu_plane_atomic_update()
497 ipu->num_w, ipu->denom_w); in ingenic_ipu_plane_atomic_update()
499 if (ipu->num_h != 1 || ipu->denom_h != 1) in ingenic_ipu_plane_atomic_update()
500 ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_VRSZ_COEF_LUT, in ingenic_ipu_plane_atomic_update()
501 ipu->num_h, ipu->denom_h); in ingenic_ipu_plane_atomic_update()
504 regmap_write(ipu->map, JZ_REG_IPU_STATUS, 0); in ingenic_ipu_plane_atomic_update()
506 /* Start IPU */ in ingenic_ipu_plane_atomic_update()
507 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, in ingenic_ipu_plane_atomic_update()
510 dev_dbg(ipu->dev, "Scaling %ux%u to %ux%u (%u:%u horiz, %u:%u vert)\n", in ingenic_ipu_plane_atomic_update()
513 ipu->num_w, ipu->denom_w, ipu->num_h, ipu->denom_h); in ingenic_ipu_plane_atomic_update()
520 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_check() local
531 /* Request a full modeset if we are enabling or disabling the IPU. */ in ingenic_ipu_plane_atomic_check()
576 ipu->num_w = num_w; in ingenic_ipu_plane_atomic_check()
577 ipu->num_h = num_h; in ingenic_ipu_plane_atomic_check()
578 ipu->denom_w = denom_w; in ingenic_ipu_plane_atomic_check()
579 ipu->denom_h = denom_h; in ingenic_ipu_plane_atomic_check()
587 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_disable() local
589 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_STOP); in ingenic_ipu_plane_atomic_disable()
590 regmap_clear_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_CHIP_EN); in ingenic_ipu_plane_atomic_disable()
592 ingenic_drm_plane_disable(ipu->master, plane); in ingenic_ipu_plane_atomic_disable()
594 if (ipu->clk_enabled) { in ingenic_ipu_plane_atomic_disable()
595 clk_disable(ipu->clk); in ingenic_ipu_plane_atomic_disable()
596 ipu->clk_enabled = false; in ingenic_ipu_plane_atomic_disable()
612 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_get_property() local
614 if (property != ipu->sharpness_prop) in ingenic_ipu_plane_atomic_get_property()
617 *val = ipu->sharpness; in ingenic_ipu_plane_atomic_get_property()
627 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_set_property() local
630 if (property != ipu->sharpness_prop) in ingenic_ipu_plane_atomic_set_property()
633 ipu->sharpness = val; in ingenic_ipu_plane_atomic_set_property()
661 struct ingenic_ipu *ipu = arg; in ingenic_ipu_irq_handler() local
662 struct drm_crtc *crtc = drm_crtc_from_index(ipu->drm, 0); in ingenic_ipu_irq_handler()
665 /* dummy read allows CPU to reconfigure IPU */ in ingenic_ipu_irq_handler()
666 if (ipu->soc_info->manual_restart) in ingenic_ipu_irq_handler()
667 regmap_read(ipu->map, JZ_REG_IPU_STATUS, &dummy); in ingenic_ipu_irq_handler()
670 regmap_write(ipu->map, JZ_REG_IPU_STATUS, 0); in ingenic_ipu_irq_handler()
673 regmap_write(ipu->map, JZ_REG_IPU_Y_ADDR, ipu->addr_y); in ingenic_ipu_irq_handler()
674 regmap_write(ipu->map, JZ_REG_IPU_U_ADDR, ipu->addr_u); in ingenic_ipu_irq_handler()
675 regmap_write(ipu->map, JZ_REG_IPU_V_ADDR, ipu->addr_v); in ingenic_ipu_irq_handler()
677 /* Run IPU for the new frame */ in ingenic_ipu_irq_handler()
678 if (ipu->soc_info->manual_restart) in ingenic_ipu_irq_handler()
679 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_RUN); in ingenic_ipu_irq_handler()
700 struct ingenic_ipu *ipu; in ingenic_ipu_bind() local
705 ipu = devm_kzalloc(dev, sizeof(*ipu), GFP_KERNEL); in ingenic_ipu_bind()
706 if (!ipu) in ingenic_ipu_bind()
715 ipu->dev = dev; in ingenic_ipu_bind()
716 ipu->drm = drm; in ingenic_ipu_bind()
717 ipu->master = master; in ingenic_ipu_bind()
718 ipu->soc_info = soc_info; in ingenic_ipu_bind()
726 ipu->map = devm_regmap_init_mmio(dev, base, &ingenic_ipu_regmap_config); in ingenic_ipu_bind()
727 if (IS_ERR(ipu->map)) { in ingenic_ipu_bind()
729 return PTR_ERR(ipu->map); in ingenic_ipu_bind()
736 ipu->clk = devm_clk_get(dev, "ipu"); in ingenic_ipu_bind()
737 if (IS_ERR(ipu->clk)) { in ingenic_ipu_bind()
739 return PTR_ERR(ipu->clk); in ingenic_ipu_bind()
743 dev_name(dev), ipu); in ingenic_ipu_bind()
749 plane = &ipu->plane; in ingenic_ipu_bind()
769 ipu->sharpness_prop = drm_property_create_range(drm, 0, "sharpness", in ingenic_ipu_bind()
771 if (!ipu->sharpness_prop) { in ingenic_ipu_bind()
777 ipu->sharpness = soc_info->has_bicubic ? 8 : 1; in ingenic_ipu_bind()
778 drm_object_attach_property(&plane->base, ipu->sharpness_prop, in ingenic_ipu_bind()
779 ipu->sharpness); in ingenic_ipu_bind()
781 err = clk_prepare(ipu->clk); in ingenic_ipu_bind()
793 struct ingenic_ipu *ipu = dev_get_drvdata(dev); in ingenic_ipu_unbind() local
795 clk_unprepare(ipu->clk); in ingenic_ipu_unbind()
866 { .compatible = "ingenic,jz4725b-ipu", .data = &jz4725b_soc_info },
867 { .compatible = "ingenic,jz4760-ipu", .data = &jz4760_soc_info },
874 .name = "ingenic-ipu",