Lines Matching +full:bcm2835 +full:- +full:vec
1 // SPDX-License-Identifier: GPL-2.0-only
9 * The VEC encoder generates PAL or NTSC composite video output.
13 * PAL and PAL-M or NTSC and NTSC-J.
41 /* VEC Registers */
85 * VEC_FREQ1_0 contains the most significant 16-bit half-word,
86 * VEC_FREQ3_2 contains the least significant 16-bit half-word.
88 * (which itself is the VEC clock divided by 8).
92 * NTSC (3579545.[45] Hz) - 0x21F07C1F
93 * PAL (4433618.75 Hz) - 0x2A098ACB
94 * PAL-M (3575611.[888111] Hz) - 0x21E6EFE3
95 * PAL-N (3582056.25 Hz) - 0x21F69446
193 /* General VEC hardware state. */
213 readl(vec->regs + (offset)); \
219 writel(val, vec->regs + (offset)); \
301 /* PAL-60 */
337 if (tv_mode->mode == mode && in vc4_vec_tv_mode_lookup()
338 tv_mode->expected_htotal == htotal) in vc4_vec_tv_mode_lookup()
347 { VC4_VEC_TV_MODE_NTSC_443, "NTSC-443", },
348 { VC4_VEC_TV_MODE_NTSC_J, "NTSC-J", },
350 { VC4_VEC_TV_MODE_PAL_60, "PAL-60", },
351 { VC4_VEC_TV_MODE_PAL_M, "PAL-M", },
352 { VC4_VEC_TV_MODE_PAL_N, "PAL-N", },
374 struct vc4_vec *vec = connector_to_vc4_vec(connector); in vc4_vec_connector_set_property() local
376 if (property != vec->legacy_tv_mode_property) in vc4_vec_connector_set_property()
377 return -EINVAL; in vc4_vec_connector_set_property()
381 state->tv.mode = DRM_MODE_TV_MODE_NTSC; in vc4_vec_connector_set_property()
385 state->tv.mode = DRM_MODE_TV_MODE_NTSC_443; in vc4_vec_connector_set_property()
389 state->tv.mode = DRM_MODE_TV_MODE_NTSC_J; in vc4_vec_connector_set_property()
394 state->tv.mode = DRM_MODE_TV_MODE_PAL; in vc4_vec_connector_set_property()
398 state->tv.mode = DRM_MODE_TV_MODE_PAL_M; in vc4_vec_connector_set_property()
402 state->tv.mode = DRM_MODE_TV_MODE_PAL_N; in vc4_vec_connector_set_property()
406 state->tv.mode = DRM_MODE_TV_MODE_SECAM; in vc4_vec_connector_set_property()
410 return -EINVAL; in vc4_vec_connector_set_property()
422 struct vc4_vec *vec = connector_to_vc4_vec(connector); in vc4_vec_connector_get_property() local
424 if (property != vec->legacy_tv_mode_property) in vc4_vec_connector_get_property()
425 return -EINVAL; in vc4_vec_connector_get_property()
427 switch (state->tv.mode) { in vc4_vec_connector_get_property()
457 return -EINVAL; in vc4_vec_connector_get_property()
478 static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) in vc4_vec_connector_init() argument
480 struct drm_connector *connector = &vec->connector; in vc4_vec_connector_init()
484 connector->interlace_allowed = true; in vc4_vec_connector_init()
493 drm_object_attach_property(&connector->base, in vc4_vec_connector_init()
494 dev->mode_config.tv_mode_property, in vc4_vec_connector_init()
501 return -ENOMEM; in vc4_vec_connector_init()
502 vec->legacy_tv_mode_property = prop; in vc4_vec_connector_init()
504 drm_object_attach_property(&connector->base, prop, VC4_VEC_TV_MODE_NTSC); in vc4_vec_connector_init()
506 drm_connector_attach_encoder(connector, &vec->encoder.base); in vc4_vec_connector_init()
514 struct drm_device *drm = encoder->dev; in vc4_vec_encoder_disable()
515 struct vc4_vec *vec = encoder_to_vc4_vec(encoder); in vc4_vec_encoder_disable() local
528 clk_disable_unprepare(vec->clock); in vc4_vec_encoder_disable()
530 ret = pm_runtime_put(&vec->pdev->dev); in vc4_vec_encoder_disable()
546 struct drm_device *drm = encoder->dev; in vc4_vec_encoder_enable()
547 struct vc4_vec *vec = encoder_to_vc4_vec(encoder); in vc4_vec_encoder_enable() local
548 struct drm_connector *connector = &vec->connector; in vc4_vec_encoder_enable()
552 &encoder->crtc->state->adjusted_mode; in vc4_vec_encoder_enable()
559 tv_mode = vc4_vec_tv_mode_lookup(conn_state->tv.mode, in vc4_vec_encoder_enable()
560 adjusted_mode->htotal); in vc4_vec_encoder_enable()
564 ret = pm_runtime_resume_and_get(&vec->pdev->dev); in vc4_vec_encoder_enable()
577 ret = clk_set_rate(vec->clock, 108000000); in vc4_vec_encoder_enable()
583 ret = clk_prepare_enable(vec->clock); in vc4_vec_encoder_enable()
593 /* Disable the CGSM-A and WSE blocks */ in vc4_vec_encoder_enable()
612 ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 0 : VEC_CONFIG2_PROG_SCAN)); in vc4_vec_encoder_enable()
614 VEC_WRITE(VEC_DAC_CONFIG, vec->variant->dac_config); in vc4_vec_encoder_enable()
619 VEC_WRITE(VEC_CONFIG0, tv_mode->config0); in vc4_vec_encoder_enable()
620 VEC_WRITE(VEC_CONFIG1, tv_mode->config1); in vc4_vec_encoder_enable()
622 if (tv_mode->custom_freq) { in vc4_vec_encoder_enable()
624 (tv_mode->custom_freq >> 16) & 0xffff); in vc4_vec_encoder_enable()
626 tv_mode->custom_freq & 0xffff); in vc4_vec_encoder_enable()
637 pm_runtime_put(&vec->pdev->dev); in vc4_vec_encoder_enable()
646 const struct drm_display_mode *mode = &crtc_state->adjusted_mode; in vc4_vec_encoder_atomic_check()
649 tv_mode = vc4_vec_tv_mode_lookup(conn_state->tv.mode, mode->htotal); in vc4_vec_encoder_atomic_check()
651 return -EINVAL; in vc4_vec_encoder_atomic_check()
653 if (mode->crtc_hdisplay % 4) in vc4_vec_encoder_atomic_check()
654 return -EINVAL; in vc4_vec_encoder_atomic_check()
656 if (!(mode->crtc_hsync_end - mode->crtc_hsync_start)) in vc4_vec_encoder_atomic_check()
657 return -EINVAL; in vc4_vec_encoder_atomic_check()
659 switch (mode->htotal) { in vc4_vec_encoder_atomic_check()
662 if (mode->crtc_vtotal > 262) in vc4_vec_encoder_atomic_check()
663 return -EINVAL; in vc4_vec_encoder_atomic_check()
665 if (mode->crtc_vdisplay < 1 || mode->crtc_vdisplay > 253) in vc4_vec_encoder_atomic_check()
666 return -EINVAL; in vc4_vec_encoder_atomic_check()
668 if (!(mode->crtc_vsync_start - mode->crtc_vdisplay)) in vc4_vec_encoder_atomic_check()
669 return -EINVAL; in vc4_vec_encoder_atomic_check()
671 if ((mode->crtc_vsync_end - mode->crtc_vsync_start) != 3) in vc4_vec_encoder_atomic_check()
672 return -EINVAL; in vc4_vec_encoder_atomic_check()
674 if ((mode->crtc_vtotal - mode->crtc_vsync_end) < 4) in vc4_vec_encoder_atomic_check()
675 return -EINVAL; in vc4_vec_encoder_atomic_check()
681 if (mode->crtc_vtotal > 312) in vc4_vec_encoder_atomic_check()
682 return -EINVAL; in vc4_vec_encoder_atomic_check()
684 if (mode->crtc_vdisplay < 1 || mode->crtc_vdisplay > 305) in vc4_vec_encoder_atomic_check()
685 return -EINVAL; in vc4_vec_encoder_atomic_check()
687 if (!(mode->crtc_vsync_start - mode->crtc_vdisplay)) in vc4_vec_encoder_atomic_check()
688 return -EINVAL; in vc4_vec_encoder_atomic_check()
690 if ((mode->crtc_vsync_end - mode->crtc_vsync_start) != 3) in vc4_vec_encoder_atomic_check()
691 return -EINVAL; in vc4_vec_encoder_atomic_check()
693 if ((mode->crtc_vtotal - mode->crtc_vsync_end) < 2) in vc4_vec_encoder_atomic_check()
694 return -EINVAL; in vc4_vec_encoder_atomic_check()
699 return -EINVAL; in vc4_vec_encoder_atomic_check()
713 struct drm_device *drm = encoder->dev; in vc4_vec_late_register()
714 struct vc4_vec *vec = encoder_to_vc4_vec(encoder); in vc4_vec_late_register() local
716 vc4_debugfs_add_regset32(drm, "vec_regs", &vec->regset); in vc4_vec_late_register()
738 { .compatible = "brcm,bcm2835-vec", .data = &bcm2835_vec_variant },
739 { .compatible = "brcm,bcm2711-vec", .data = &bcm2711_vec_variant },
747 struct vc4_vec *vec; in vc4_vec_bind() local
761 vec = drmm_kzalloc(drm, sizeof(*vec), GFP_KERNEL); in vc4_vec_bind()
762 if (!vec) in vc4_vec_bind()
763 return -ENOMEM; in vc4_vec_bind()
765 vec->encoder.type = VC4_ENCODER_TYPE_VEC; in vc4_vec_bind()
766 vec->pdev = pdev; in vc4_vec_bind()
767 vec->variant = (const struct vc4_vec_variant *) in vc4_vec_bind()
769 vec->regs = vc4_ioremap_regs(pdev, 0); in vc4_vec_bind()
770 if (IS_ERR(vec->regs)) in vc4_vec_bind()
771 return PTR_ERR(vec->regs); in vc4_vec_bind()
772 vec->regset.base = vec->regs; in vc4_vec_bind()
773 vec->regset.regs = vec_regs; in vc4_vec_bind()
774 vec->regset.nregs = ARRAY_SIZE(vec_regs); in vc4_vec_bind()
776 vec->clock = devm_clk_get(dev, NULL); in vc4_vec_bind()
777 if (IS_ERR(vec->clock)) { in vc4_vec_bind()
778 ret = PTR_ERR(vec->clock); in vc4_vec_bind()
779 if (ret != -EPROBE_DEFER) in vc4_vec_bind()
788 ret = drmm_encoder_init(drm, &vec->encoder.base, in vc4_vec_bind()
795 drm_encoder_helper_add(&vec->encoder.base, &vc4_vec_encoder_helper_funcs); in vc4_vec_bind()
797 ret = vc4_vec_connector_init(drm, vec); in vc4_vec_bind()
801 dev_set_drvdata(dev, vec); in vc4_vec_bind()
812 return component_add(&pdev->dev, &vc4_vec_ops); in vc4_vec_dev_probe()
817 component_del(&pdev->dev, &vc4_vec_ops); in vc4_vec_dev_remove()