Lines Matching full:ipu
3 // Ingenic JZ47xx IPU driver
9 #include "ingenic-ipu.h"
43 void (*set_coefs)(struct ingenic_ipu *ipu, unsigned int reg,
155 static void jz4760_set_coefs(struct ingenic_ipu *ipu, unsigned int reg, in jz4760_set_coefs() argument
199 regmap_write(ipu->map, reg, val); in jz4760_set_coefs()
204 regmap_write(ipu->map, reg, val); in jz4760_set_coefs()
207 static void jz4725b_set_coefs(struct ingenic_ipu *ipu, unsigned int reg, in jz4725b_set_coefs() argument
223 regmap_write(ipu->map, reg, val); in jz4725b_set_coefs()
227 regmap_write(ipu->map, reg, JZ4725B_IPU_RSZ_LUT_IN_EN); in jz4725b_set_coefs()
231 static void ingenic_ipu_set_downscale_coefs(struct ingenic_ipu *ipu, in ingenic_ipu_set_downscale_coefs() argument
244 ipu->soc_info->set_coefs(ipu, reg, ipu->sharpness, in ingenic_ipu_set_downscale_coefs()
249 static void ingenic_ipu_set_integer_upscale_coefs(struct ingenic_ipu *ipu, in ingenic_ipu_set_integer_upscale_coefs() argument
260 ipu->soc_info->set_coefs(ipu, reg, 0, false, 512, i == num - 1); in ingenic_ipu_set_integer_upscale_coefs()
263 static void ingenic_ipu_set_upscale_coefs(struct ingenic_ipu *ipu, in ingenic_ipu_set_upscale_coefs() argument
278 ipu->soc_info->set_coefs(ipu, reg, ipu->sharpness, in ingenic_ipu_set_upscale_coefs()
283 static void ingenic_ipu_set_coefs(struct ingenic_ipu *ipu, unsigned int reg, in ingenic_ipu_set_coefs() argument
287 regmap_write(ipu->map, reg, -1); in ingenic_ipu_set_coefs()
290 ingenic_ipu_set_downscale_coefs(ipu, reg, num, denom); in ingenic_ipu_set_coefs()
292 ingenic_ipu_set_integer_upscale_coefs(ipu, reg, num); in ingenic_ipu_set_coefs()
294 ingenic_ipu_set_upscale_coefs(ipu, reg, num, denom); in ingenic_ipu_set_coefs()
326 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_update() local
338 ipu_state = ingenic_ipu_get_new_priv_state(ipu, state); in ingenic_ipu_plane_atomic_update()
344 if (!ipu->clk_enabled) { in ingenic_ipu_plane_atomic_update()
345 err = clk_enable(ipu->clk); in ingenic_ipu_plane_atomic_update()
347 dev_err(ipu->dev, "Unable to enable clock: %d\n", err); in ingenic_ipu_plane_atomic_update()
351 ipu->clk_enabled = true; in ingenic_ipu_plane_atomic_update()
357 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_RST); in ingenic_ipu_plane_atomic_update()
360 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, in ingenic_ipu_plane_atomic_update()
364 if (ingenic_drm_map_noncoherent(ipu->master)) in ingenic_ipu_plane_atomic_update()
365 drm_fb_dma_sync_non_coherent(ipu->drm, oldstate, newstate); in ingenic_ipu_plane_atomic_update()
368 ipu->addr_y = drm_fb_dma_get_gem_addr(newstate->fb, newstate, 0); in ingenic_ipu_plane_atomic_update()
370 ipu->addr_u = drm_fb_dma_get_gem_addr(newstate->fb, newstate, in ingenic_ipu_plane_atomic_update()
373 ipu->addr_v = drm_fb_dma_get_gem_addr(newstate->fb, newstate, in ingenic_ipu_plane_atomic_update()
380 regmap_write(ipu->map, JZ_REG_IPU_Y_ADDR, ipu->addr_y); in ingenic_ipu_plane_atomic_update()
381 regmap_write(ipu->map, JZ_REG_IPU_U_ADDR, ipu->addr_u); in ingenic_ipu_plane_atomic_update()
382 regmap_write(ipu->map, JZ_REG_IPU_V_ADDR, ipu->addr_v); in ingenic_ipu_plane_atomic_update()
385 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_SPKG_SEL); in ingenic_ipu_plane_atomic_update()
387 ingenic_drm_plane_config(ipu->master, plane, DRM_FORMAT_XRGB8888); in ingenic_ipu_plane_atomic_update()
398 regmap_write(ipu->map, JZ_REG_IPU_UV_STRIDE, stride); in ingenic_ipu_plane_atomic_update()
401 regmap_write(ipu->map, JZ_REG_IPU_Y_STRIDE, stride); in ingenic_ipu_plane_atomic_update()
403 regmap_write(ipu->map, JZ_REG_IPU_IN_GS, in ingenic_ipu_plane_atomic_update()
470 regmap_write(ipu->map, JZ_REG_IPU_D_FMT, format); in ingenic_ipu_plane_atomic_update()
473 regmap_write(ipu->map, JZ_REG_IPU_OUT_GS, in ingenic_ipu_plane_atomic_update()
476 regmap_write(ipu->map, JZ_REG_IPU_OUT_STRIDE, newstate->crtc_w * 4); in ingenic_ipu_plane_atomic_update()
479 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_CSC_EN); in ingenic_ipu_plane_atomic_update()
487 regmap_write(ipu->map, JZ_REG_IPU_CSC_OFFSET, in ingenic_ipu_plane_atomic_update()
497 regmap_write(ipu->map, JZ_REG_IPU_CSC_C0_COEF, 0x4a8); in ingenic_ipu_plane_atomic_update()
498 regmap_write(ipu->map, JZ_REG_IPU_CSC_C1_COEF, 0x662); in ingenic_ipu_plane_atomic_update()
499 regmap_write(ipu->map, JZ_REG_IPU_CSC_C2_COEF, 0x191); in ingenic_ipu_plane_atomic_update()
500 regmap_write(ipu->map, JZ_REG_IPU_CSC_C3_COEF, 0x341); in ingenic_ipu_plane_atomic_update()
501 regmap_write(ipu->map, JZ_REG_IPU_CSC_C4_COEF, 0x811); in ingenic_ipu_plane_atomic_update()
508 * If the IPU supports bicubic, we enable it unconditionally, since it in ingenic_ipu_plane_atomic_update()
511 if (ipu->soc_info->has_bicubic) in ingenic_ipu_plane_atomic_update()
519 if (!ipu->soc_info->has_bicubic && !upscaling_w) in ingenic_ipu_plane_atomic_update()
531 if (!ipu->soc_info->has_bicubic && !upscaling_h) in ingenic_ipu_plane_atomic_update()
538 regmap_update_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_ZOOM_SEL | in ingenic_ipu_plane_atomic_update()
543 regmap_write(ipu->map, JZ_REG_IPU_RSZ_COEF_INDEX, coef_index); in ingenic_ipu_plane_atomic_update()
546 ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_HRSZ_COEF_LUT, in ingenic_ipu_plane_atomic_update()
550 ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_VRSZ_COEF_LUT, in ingenic_ipu_plane_atomic_update()
554 regmap_write(ipu->map, JZ_REG_IPU_STATUS, 0); in ingenic_ipu_plane_atomic_update()
556 /* Start IPU */ in ingenic_ipu_plane_atomic_update()
557 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, in ingenic_ipu_plane_atomic_update()
560 dev_dbg(ipu->dev, "Scaling %ux%u to %ux%u (%u:%u horiz, %u:%u vert)\n", in ingenic_ipu_plane_atomic_update()
575 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_check() local
587 ipu_state = ingenic_ipu_get_priv_state(ipu, state); in ingenic_ipu_plane_atomic_check()
591 /* Request a full modeset if we are enabling or disabling the IPU. */ in ingenic_ipu_plane_atomic_check()
649 if (ingenic_drm_map_noncoherent(ipu->master)) in ingenic_ipu_plane_atomic_check()
658 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_disable() local
660 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_STOP); in ingenic_ipu_plane_atomic_disable()
661 regmap_clear_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_CHIP_EN); in ingenic_ipu_plane_atomic_disable()
663 ingenic_drm_plane_disable(ipu->master, plane); in ingenic_ipu_plane_atomic_disable()
665 if (ipu->clk_enabled) { in ingenic_ipu_plane_atomic_disable()
666 clk_disable(ipu->clk); in ingenic_ipu_plane_atomic_disable()
667 ipu->clk_enabled = false; in ingenic_ipu_plane_atomic_disable()
682 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_get_property() local
684 if (property != ipu->sharpness_prop) in ingenic_ipu_plane_atomic_get_property()
687 *val = ipu->sharpness; in ingenic_ipu_plane_atomic_get_property()
697 struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); in ingenic_ipu_plane_atomic_set_property() local
701 if (property != ipu->sharpness_prop) in ingenic_ipu_plane_atomic_set_property()
704 mode_changed = val != ipu->sharpness; in ingenic_ipu_plane_atomic_set_property()
705 ipu->sharpness = val; in ingenic_ipu_plane_atomic_set_property()
760 struct ingenic_ipu *ipu = arg; in ingenic_ipu_irq_handler() local
761 struct drm_crtc *crtc = drm_crtc_from_index(ipu->drm, 0); in ingenic_ipu_irq_handler()
764 /* dummy read allows CPU to reconfigure IPU */ in ingenic_ipu_irq_handler()
765 if (ipu->soc_info->manual_restart) in ingenic_ipu_irq_handler()
766 regmap_read(ipu->map, JZ_REG_IPU_STATUS, &dummy); in ingenic_ipu_irq_handler()
769 regmap_write(ipu->map, JZ_REG_IPU_STATUS, 0); in ingenic_ipu_irq_handler()
772 regmap_write(ipu->map, JZ_REG_IPU_Y_ADDR, ipu->addr_y); in ingenic_ipu_irq_handler()
773 regmap_write(ipu->map, JZ_REG_IPU_U_ADDR, ipu->addr_u); in ingenic_ipu_irq_handler()
774 regmap_write(ipu->map, JZ_REG_IPU_V_ADDR, ipu->addr_v); in ingenic_ipu_irq_handler()
776 /* Run IPU for the new frame */ in ingenic_ipu_irq_handler()
777 if (ipu->soc_info->manual_restart) in ingenic_ipu_irq_handler()
778 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_RUN); in ingenic_ipu_irq_handler()
800 struct ingenic_ipu *ipu; in ingenic_ipu_bind() local
805 ipu = devm_kzalloc(dev, sizeof(*ipu), GFP_KERNEL); in ingenic_ipu_bind()
806 if (!ipu) in ingenic_ipu_bind()
815 ipu->dev = dev; in ingenic_ipu_bind()
816 ipu->drm = drm; in ingenic_ipu_bind()
817 ipu->master = master; in ingenic_ipu_bind()
818 ipu->soc_info = soc_info; in ingenic_ipu_bind()
826 ipu->map = devm_regmap_init_mmio(dev, base, &ingenic_ipu_regmap_config); in ingenic_ipu_bind()
827 if (IS_ERR(ipu->map)) { in ingenic_ipu_bind()
829 return PTR_ERR(ipu->map); in ingenic_ipu_bind()
836 ipu->clk = devm_clk_get(dev, "ipu"); in ingenic_ipu_bind()
837 if (IS_ERR(ipu->clk)) { in ingenic_ipu_bind()
839 return PTR_ERR(ipu->clk); in ingenic_ipu_bind()
843 dev_name(dev), ipu); in ingenic_ipu_bind()
849 plane = &ipu->plane; in ingenic_ipu_bind()
872 ipu->sharpness_prop = drm_property_create_range(drm, 0, "sharpness", in ingenic_ipu_bind()
874 if (!ipu->sharpness_prop) { in ingenic_ipu_bind()
880 ipu->sharpness = soc_info->has_bicubic ? 8 : 1; in ingenic_ipu_bind()
881 drm_object_attach_property(&plane->base, ipu->sharpness_prop, in ingenic_ipu_bind()
882 ipu->sharpness); in ingenic_ipu_bind()
884 err = clk_prepare(ipu->clk); in ingenic_ipu_bind()
896 drm_atomic_private_obj_init(drm, &ipu->private_obj, &private_state->base, in ingenic_ipu_bind()
902 clk_unprepare(ipu->clk); in ingenic_ipu_bind()
909 struct ingenic_ipu *ipu = dev_get_drvdata(dev); in ingenic_ipu_unbind() local
911 drm_atomic_private_obj_fini(&ipu->private_obj); in ingenic_ipu_unbind()
912 clk_unprepare(ipu->clk); in ingenic_ipu_unbind()
983 { .compatible = "ingenic,jz4725b-ipu", .data = &jz4725b_soc_info },
984 { .compatible = "ingenic,jz4760-ipu", .data = &jz4760_soc_info },
991 .name = "ingenic-ipu",