rockchip-linux / kernel

BSP kernel source
Other
912 stars 1.07k forks source link

rk3328 TV encoder #307

Open strobo5 opened 11 months ago

strobo5 commented 11 months ago

They say that on the internet that whatever you do or like, you are never the only one. How about enabling the composite video output on a Rock64 with mainline linux? I feel that a lot of work went into rockchip_drm to be part of mainline Linux, and so little is missing for the TV out! The usual trap.

I copied rockchip_drm_tve.c and related code into stable Linux v6.2.8 (as used by PostmarketOS). See here: https://github.com/strobo5/linux/compare/v6.2.8...strobo5:linux:rockchip_drm_tve?expand

I get so far that in Linux it looks like the TV encoder is active, and on the oscilloscope I can see the HSYNC pulses and the image signal for each line. This signal changes when I do kmscube, for example, so the pipeline seems to work in general. But I think VSYNC is missing?! The TV does not display an image.

# dmesg | grep tve
[    0.000000] Kernel command line: console=tty0 console=ttyS2,1500000n8 panic=10 coherent_pool=1M video=TV-1:720x576i@50.00 loglevel=7 PMOS_NO_OUTPUT_REDIRECT  pmos_boot_uuid=073d6741-4df0-4ae2-abd6-989ac0733e22 pmos_root_uuid=01dad8dc-81bb-42f6-88d6-484cc07f556a dyndbg="file rockchip_drm_tve.c +p" dynamic_debug.verbose=1
[    0.022357] dyndbg: dyndbg="file rockchip_drm_tve.c +p"
[    0.022380] dyndbg: query 0: "file rockchip_drm_tve.c +p" mod:*
[    0.082827] platform ff373e00.tve: Fixing up cyclic dependency with ff370000.vop
[    0.739012] rockchip-tve ff373e00.tve: failed to get id cell: -2
[    0.739061] rockchip-tve ff373e00.tve: possible_crtc:1
[    0.739106] rockchip-tve ff373e00.tve: rockchip,rk3328-tve tv encoder probe ok
[    0.739122] rockchip-drm display-subsystem: bound ff373e00.tve (ops rockchip_tve_component_ops)
[    0.746811] rockchip-tve ff373e00.tve: encoder mode set:720x576i
[    0.747563] rockchip-tve ff373e00.tve: tve encoder enable
[    0.747574] rockchip-tve ff373e00.tve: cvbs_set_enable
[    0.747588] rockchip-tve ff373e00.tve: dac enable
[    0.747597] rockchip-tve ff373e00.tve: tve set mode:1
[    0.747608] rockchip-tve ff373e00.tve: PAL MODE
[  333.541737] rockchip-tve ff373e00.tve: tve encoder enable
[  333.541761] rockchip-tve ff373e00.tve: cvbs_set_disable
[  333.541783] rockchip-tve ff373e00.tve: dac disable

I have to disable HDMI in the device tree, or it doesn't seem to work at all.

I also tried building the kernel from this repo but there were errors and I gave up.

I'm out of clues, any help is appreciated. Some logs are attached. Otherwise, let's enjoy together three lines of kmscube as the analog output signal on the analog scope in the image below.

dmesg_nohdmi_tve_debug.log dri_0_state.log drm_info.log modeprint.log img1

strobo5 commented 10 months ago

The vertical synchronization is okay now, I can make out the 50 Hz sync pulses on the oscilloscope.

But now the rest of the signal is wrong. The colorburst is overlaid with another signal, and the actual image data seems to be out of sync with the 50 Hz.

I'm out of time and ideas again. Maybe based on this information somebody has a clue what the reason might be.

Attached are the output of cat /sys/kernel/debug/clk/clk_summary and four images:

clk_summary.log IMG_20231002_213357_mod IMG_20231002_214456_shrinked IMG_20231002_213608 IMG_20231002_213610

strobo5 commented 10 months ago

I had missed the part of drivers/gpu/drm/rockchip/rockchip_drm_vop.c that sets up the interlacing mode. But I can't get that to work properly.

The way I see it, two different "line flag" interrupts are generated when interlacing is enabled, at lines defined by line_flag_num[0] and line_flag_num[1]. Not sure if LINE_FLAG1_INTR is actually being used or not.

Also, on this VOP version (major 3, minor 8), the vblank interrupt used by rockchip-linux is FS_FIELD_INTR instead of FS_INTR. No idea why. The mainline source always uses FS_INTR.

kmscube now renders at 25 FPS, with the enabled interlacing, so the vblank interrupt might be correct (if this is what kmscube syncs on).

The video output now shows something less broken: the kmscube rendering appears stable. But on the oscilloscope I see the vsync pulse + horizontal scans with image information only every 80 ms. Also the stripe on the left edge persists. IMG_20231008_171427

I updated my branch of mainline v6.2.8 (see original message) before now giving up.

strobo5 commented 10 months ago

With some debug output I had noticed that in vop_crtc_atomic_enable() there is a check for vdisplay == 288 and that the actual value was twice (576). And also I had seen it being 288 in vop_plane_atomic_check(). So what's the difference? The former was not using the CRTC timings with the crtc_ prefix which are adjusted for interlaced modes. See https://github.com/strobo5/linux/commit/f5db0600a2d9265f66c7b26da0d6f0e0bca3e69f.

Now it looks more or less okay, just there is a black vertical stripe on the left edge.