Skip to content

RP1 DPI: Add interlaced modes - #6529

Merged
pelwell merged 3 commits into
raspberrypi:rpi-6.6.yfrom
njhollinghurst:dpi-interlace2
Dec 11, 2024
Merged

pelwell merged 3 commits into
raspberrypi:rpi-6.6.yfrom
njhollinghurst:dpi-interlace2

Conversation

@njhollinghurst

Copy link
Copy Markdown
Contributor

Add support for interlaced DPI modes on Raspberry Pi 5. (Draft for testing, based on rpi-6.6.y)

In order for this to work correctly, DPI's DE output must be enabled on GPIO1 (whether used or not). PIO can then snoop on DE and HSYNC signals to generate a fixed-up VSYNC on GPIO2.

This is the cut-down version of the patch which omits CSYNC support, but it should still be possible to implement CSYNC (and equalizing pulses) using an external PIO program; I will need to update the example in utils/piolib/examples.

Comment thread drivers/gpu/drm/bridge/panel.c
Comment thread drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi_hw.c Outdated
BITS(DPI_DMA_FRONT_PORCH_COLSM1, mode->hsync_start - mode->hdisplay - 1));

vctrl = BITS(DPI_DMA_CONTROL_VSYNC_POL, !!(mode->flags & DRM_MODE_FLAG_NVSYNC)) |
BITS(DPI_DMA_CONTROL_VBP_EN, (mode->vtotal != mode->vsync_start)) |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the excess white space. Normal coding style wouldn't align this type, only in tables.

* based on HSYNC, DE (which *must* both be mapped to GPIOs 1, 3 respectively).
* This driver includes a PIO program to do that, when DE is enabled.
*
* An alternative fixup is to synthesize CSYNC from HSYNC and modified-VSYNC.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you still got CSYNC support? I thought you'd said it had been dropped.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DPI VSYNC waveform is somewhat arbitrary (since it can't be correct for interlace). Here it's designed to assist CSYNC generation. But I removed the PIO code that actually does generate CSYNC (for code bloat reduction).

{
static const int wrap_target = 14;
static const int wrap = 26;
u16 instructions[] = { /* This is mutable */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using statics means we can't instantiate the driver twice. Unlikely ever to happen, but I'd be tempted to put it in struct rpi1_dpi instead.

@njhollinghurst njhollinghurst Dec 10, 2024 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are just named constants. The PIO compiler spits out lower-case #defines but I avoided those because they seemed unsightly, and there were formerly 3 different functions that defined similar-named constants differently.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd misread instructions as being static.

I assume the program gets copied into RP1 / PIO in some shape or form, so this doesn't need to remain in context after the pio_add_program call.

@njhollinghurst njhollinghurst Dec 10, 2024 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it's the other way around: instructions[] is mutable because it gets subjected to some runtime fixups (rather than have 4 or 8 different versions for different sync polarities). But I can change the style if it's unclear.

I assumed (perhaps wrongly) that using a run-time initializer is no less efficient than explicitly making a copy. And yes, it's not needed once it's been loaded into PIO instruction memory.

@6by9

6by9 commented Dec 10, 2024

Copy link
Copy Markdown
Contributor

BTW I've just noticed that the BITS macro is a roll-it-yourself shift.
There are macros FIELD_FIT FIELD_PREP, and FIELD_SET in include/linux/bitfield.h which also do size checking to ensure you don't end up writing too many bits into a field. See vc4_regs.h for example usage.

@njhollinghurst

njhollinghurst commented Dec 10, 2024 •

Copy link
Copy Markdown
Contributor Author

There are macros FIELD_FIT FIELD_PREP, and FIELD_SET in include/linux/bitfield.h which also do size checking to ensure you don't end up writing too many bits into a field. See vc4_regs.h for example usage.

I'll see if I can use those... I'd like to keep the field definitions unmodified though, as they're taken straight from VRBuild output. Oh, I see that I've already edited them since the VRB.

@njhollinghurst

njhollinghurst commented Dec 11, 2024 •

Copy link
Copy Markdown
Contributor Author

OK I just need to check it still works with the external/example program, and may adjust the offset of the "VSync helper" signal (which should make no difference to the built-in H/VSync case, that doesn't use it).

Would be nice to keep the door open for equalizing pulses, but as the generally-accepted "PAL" modeline has 576 complete lines, and I don't want to make a special case for it, it seems slightly doomed: obviously we can't put an equalizing pulse in the middle of an active scanline.

When initialized from panel_bridge_attach(), connector should
allow interlaced modes rather than invariably rejecting them,
so that other components can validate them.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Almost no DPI hardware supports it, but it's useful for RP1 video out.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Implement interlaced modes by wobbling the base pointer and VFP width
for every field. This results in correct pixels but incorrect VSYNC.

Now use PIO to generate a fixed-up VSYNC by sampling DE and HSYNC.
This requires DPI's DE output to be mapped to GPIO1, which we check.

When DE is not exposed, the internal fixup is disabled. VSYNC/GPIO2
becomes a modified signal, designed to help an external device or
PIO program synthesize CSYNC or VSYNC.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
@njhollinghurst
njhollinghurst marked this pull request as ready for review December 11, 2024 16:10
@pelwell
pelwell merged commit 0da5bec into raspberrypi:rpi-6.6.y Dec 11, 2024
@njhollinghurst
njhollinghurst deleted the dpi-interlace2 branch December 11, 2024 17:59
@igorpecovnik

igorpecovnik commented Dec 12, 2024 •

Copy link
Copy Markdown

This PR breaks our auto-compilation:
https://github.com/armbian/os/actions/runs/12292566594/job/34305984530
https://paste.armbian.de/qiqusamowu

   ERROR: modpost: "pio_close" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "pio_set_error" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_sm_unclaim" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "pio_open" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_sm_claim" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_sm_init" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_sm_set_enabled" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_add_program" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_sm_exec" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   ERROR: modpost: "rp1_pio_gpio_set_function" [drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko] undefined!
   WARNING: modpost: suppressed 3 unresolved symbol warnings because there were too many)
   make[3]: *** [scripts/Makefile.modpost:145: Module.symvers] Error 1
   make[2]: *** [Makefile:1873: modpost] Error 2
   make[1]: *** [/armbian/cache/sources/linux-kernel-worktree/6.6__bcm2711__arm64/Makefile:359: __build_one_by_one] Error 2
   make: *** [Makefile:234: __sub-make] Error 2

@6by9

6by9 commented Dec 12, 2024

Copy link
Copy Markdown
Contributor

drivers/gpu/drm/rp1/rp1-dpi/Kconfig needs a depends on RP1_PIO or select RP1_PIO.

CONFIG_RP1_PIO is in our standard bcm2712_defconfig, so does that mean you're using your own?

@pelwell

pelwell commented Dec 12, 2024

Copy link
Copy Markdown
Contributor

Odd - our autobuilds are happy, as are my own builds.

Are you using a different defconfig? I notice that CONFIG_DRM_RP1_DPI is lacking a dependency on CONFIG_RP1_PIO, which could explain the build failure. However, CONFIG_PWM_PIO_RP1 is also lacking that dependency, and your build of pwm-pio-rp1 isn't failing.

@njhollinghurst

Copy link
Copy Markdown
Contributor Author

I'll fix it. I'll make it an ifdef rather than a dependency as DPI should still be usable without it (apart from the interlaced sync fixup).

@pelwell

pelwell commented Dec 12, 2024

Copy link
Copy Markdown
Contributor

I would add a select RP1_PIO in the Kconfig.

@6by9

6by9 commented Dec 12, 2024

Copy link
Copy Markdown
Contributor

I would add a select RP1_PIO in the Kconfig.

I'd agree.
It's possible to make things work with ifdef's, but it's non-trivial to ensure that all combinations of modules and built-ins are valid.

@igorpecovnik

Copy link
Copy Markdown

Are you using a different defconfig?

Yes. Still this should not break this way. I will update our configs. Thanks for the tip.

@pelwell

pelwell commented Dec 12, 2024 •

Copy link
Copy Markdown
Contributor

Be careful not to introduce a recursive dependency, as I seem to have just done.

@igorpecovnik

Copy link
Copy Markdown

Be careful not to introduce a recursive dependency,

Yeah, I just did ;)

[🔨]   drivers/misc/Kconfig:20:error: recursive dependency detected!
[🔨]   drivers/misc/Kconfig:20:	symbol RP1_PIO is selected by PWM_PIO_RP1
[🔨]   drivers/pwm/Kconfig:468:	symbol PWM_PIO_RP1 depends on FIRMWARE_RP1
[🔨]   drivers/firmware/Kconfig:156:	symbol FIRMWARE_RP1 is selected by RP1_PIO

@pelwell

pelwell commented Dec 12, 2024

Copy link
Copy Markdown
Contributor

That's a harsh test - it's objecting to "A selects B, B selects C, and A depends on C".

@pelwell

pelwell commented Dec 12, 2024 •

Copy link
Copy Markdown
Contributor

I've unbroken the builds while we come up with a better scheme.

popcornmix added a commit to raspberrypi/firmware that referenced this pull request Dec 16, 2024
kernel: RP1 DPI: Add interlaced modes
See: raspberrypi/linux#6529

kernel: ASoC: allo-piano-dac-plus: Fix volume limit locking
See: raspberrypi/linux#6532

kernel: drm: vc4: txp: Do not allow 24bpp formats when transposing
See: raspberrypi/linux#6533

kernel: ASoC: allo-piano-dac-plus: Suppress -517 errors
See: raspberrypi/linux#6534

kernel: drm: rp1: rp1-dpi: Fix optional dependency on RP1_PIO
See: raspberrypi/linux#6535

kernel: serial: sc16is7xx: announce support for SER_RS485_RTS_ON_SEND
See: raspberrypi/linux#6540
popcornmix added a commit to raspberrypi/rpi-firmware that referenced this pull request Dec 16, 2024
kernel: RP1 DPI: Add interlaced modes
See: raspberrypi/linux#6529

kernel: ASoC: allo-piano-dac-plus: Fix volume limit locking
See: raspberrypi/linux#6532

kernel: drm: vc4: txp: Do not allow 24bpp formats when transposing
See: raspberrypi/linux#6533

kernel: ASoC: allo-piano-dac-plus: Suppress -517 errors
See: raspberrypi/linux#6534

kernel: drm: rp1: rp1-dpi: Fix optional dependency on RP1_PIO
See: raspberrypi/linux#6535

kernel: serial: sc16is7xx: announce support for SER_RS485_RTS_ON_SEND
See: raspberrypi/linux#6540
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants