raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.22k stars 5.02k forks source link

HQ camera link frequency can cause GPS distruption #6004

Open 6by9 opened 9 months ago

6by9 commented 9 months ago

Describe the bug

From https://github.com/raspberrypi/libcamera/issues/43, the same issue of GPS interference has been noted on the HQ camera as well as the v3 that has already been fixed. Look at tweaking the PLL settings to move the peak away from GPS on 1575MHz.

Steps to reproduce the behaviour

See https://github.com/raspberrypi/libcamera/issues/43

Device (s)

Raspberry Pi 4 Mod. B

System

All kernels as the link frequency has never varied.

Logs

No response

Additional context

No response

kinnersley commented 2 weeks ago

Hi, any update on this? I see that it hasn't been taken on yet. Any tips on how to resolve it as I have a whole load of these cameras inside units with GPS and when then camera is on you can kiss goodbye to GPS signal!

6by9 commented 2 weeks ago

I had 30mins spare, so have done the quick patch to add it (based on imx708). https://github.com/raspberrypi/linux/pull/6468

Give it 40mins for CI to run, and you should be able to get the test kernel using sudo rpi-update pulls/6468. Please ensure anything critical is backed up first.

Same as imx708, you can load dtoverlay=imx477,link-frequency=447000000 or dtoverlay=imx477,link-frequency=453000000 to shift the link frequency by those few MHz. 447MHz needs a little more testing before merging, but 453MHz should have no issues.

kinnersley commented 2 weeks ago

This is great, I will give it a try with a new kernel.

Question...

I also have a legacy version that I need to support, with kernel 5.4.154. I build from a snapshot so I can apply code changes. Is it sufficient to just edit the line:

define IMX477_DEFAULT_LINK_FREQ 450000000

Or could that cause problems and I need to apply the other changes to make it configurable etc?

kinnersley commented 1 week ago

Ok that didn't work on the old kernel. Do I need to change some registers as well?

6by9 commented 1 week ago

Just changing IMX477_DEFAULT_LINK_FREQ will do nothing other than change the value advertised to userspace. Actually it may stop the driver probing as then the configured link frequency isn't the supposedly supported one.

If you want to do the quick hack, then changing register 0x030f from 0x96 to 0x97 or 0x98 in the table of registers would make the change without telling the rest of the system about it (it's not a critical thing for anything else to know about). Do note that it occurs multiple times.

kinnersley commented 1 week ago

I've tried it out and with a 200mm unshielded camera cable there is still some interference at 453, 456 and I even tried 459. It's better but still causing some signal loss. How high can we take the link frequency, do you know? Could it go up even higher without causing issues/damage?

kinnersley commented 1 week ago

Also is there some way of double checking that the link frequency change has worked? Something I can call to return the current link frequency?

6by9 commented 1 week ago

You could go up to 500MHz and still be compliant with the CSI2 spec v1.0 as implemented on Pi0-4. The IMX477 supports link frequencies up to 1.05GHz (2.1Gbit/s), and #6208 was trying to utilise that for Pi5 (supports up to 750MHz / 1.5Gbit/s) and getting higher frame rates at higher resolutions.

The module has been EMC tested with the values in the driver as they were at 450MHz, so any significant changes technically should result in redoing EMC testing.

v4l2-ctl --list-ctrls-menu -d /dev/v4l-subdev0 should give you a dump that includes the link frequency, such as

Image Processing Controls

                 link_frequency 0x009f0901 (intmenu): min=0 max=1 default=0 value=0 (456000000 0x1b2e0200) flags=read-only
                0: 456000000 (0x1b2e0200)
                1: -204673903784 (0xffffffd0587c1358)

(oops, I appear to have an extra entry in there - one to fix!)

Alternatively you can use i2ctransfer to manually poke the registers whilst streaming. i2ctransfer -y -f 10 w2@0x1a 0x03 0x0f r1@0x1a should read back the current value, whilst i2ctransfer -y -f 10 w3@0x1a 0x03 0x0f 0x99 would increase it to 459MHz.

6by9 commented 1 week ago

6483 to fix the link frequency menu having the rogue entry in it.

kinnersley commented 1 week ago

I get:

Cannot open device /dev/v4l-subdev0, exiting

and...

# i2ctransfer -y -t 10 w2@0x1a 0x03 0x0f r1@0x1a
Error: Unsupported option "-t"!

and...

# i2ctransfer -y w2@0x1a 0x03 0x0f r1@0x1a
Error: I2C bus name doesn't match any bus present!
6by9 commented 1 week ago

Grr, typo. -f (for force), not -t, and in the second case you've removed the 10.

kinnersley commented 1 week ago

I only have a /dev/i2c-11 and I get...

# i2ctransfer -y -f 11 w2@0x1a 0x03 0x0f r1@0x1a
Error: Sending messages failed: Operation timed out

Thanks for helping with this!

Update: sorry ignore the above, the camera wasn't running. However, even though I edited the registers in the kernel source code it is still reading as 0x96

# i2ctransfer -y -f 11 w2@0x1a 0x03 0x0f r1@0x1a
0x96

If I change the register with i2ctransfer will it change the link frequency on-the-fly?

I tried this...

# i2ctransfer -y -f 11 w3@0x1a 0x03 0x0f 0x99

Then I got:

# i2ctransfer -y -f 11 w2@0x1a 0x03 0x0f r1@0x1a
0x99

Then I stopped the camera and started it again and got:

# i2ctransfer -y -f 11 w2@0x1a 0x03 0x0f r1@0x1a
0x96
6by9 commented 1 week ago

Yes you can change the registers on the fly. I don't know why you only have an i2c-11 - something weird on your system if that's a standard Pi4.

kinnersley commented 4 days ago

I can confirm it's working in the latest Bookworm, but I've not been able to get it work with the old kernel. Would this same kernel work with Bullseye or would I need to build a custom kernel for Bullseye? I need legacy camera support and the original picamera library (otherwise I have to change a LOT of code) so need to get this hack into an older kernel somehow!

Any advice appreciated

kinnersley commented 3 days ago

Update: On bullseye I was able to pull the new kernel and apply the new link_frequency and it works fine in libcamera - can see 0x97 at 0x030f with i2ctransfer However, when using legacy camera (raspivid or picamera) the link_frequency is always 0x96 at 0x030f

Does the legacy stack override the registers in the kernel driver??

6by9 commented 3 days ago

The legacy camera stack is baked into the firmware and doesn't touch the kernel drivers at all.

And it's deprecated (replaced by libcamera), so there won't be any changes there.