Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue: 7" Touchscreen does not start correctly with DSI transactions #2521

Closed
k-quigley opened this issue Apr 20, 2018 · 57 comments
Closed

Issue: 7" Touchscreen does not start correctly with DSI transactions #2521

k-quigley opened this issue Apr 20, 2018 · 57 comments
Labels
Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator.

Comments

@k-quigley
Copy link

k-quigley commented Apr 20, 2018

Observed on: https://github.com/raspberrypi/linux/tree/rpi-4.15.y
Issue also seen with earlier kernels.

Issue is not present on 4.09.x branch.

Tested with Rpi3 and Rpi 7" Touchscreen panel
Tested with 4.15.17 from: https://github.com/raspberrypi/linux/

Raising here - to see if this behaviour is observed by others and/or someone can shed any light as to what's broken on the later kernels
The DSI transaction patch is required (see below) to force 7" panel to initialze using DSI and not I2C. I2C support is a quirk of this specific panel

A working vc4_dsi is needed to be able to support initialization of other display devices on the 15way DSI connector.

Steps to reproduce:
Enable raspberrypi touchscreen driver in devicetree (e.g. anholt@d7fc047)
Enable DSI transactions to startup the panel (e.g. anholt@1d460b1)

Build kernel and apply to stock raspbian image.

Configure the firmware to not load support for LCD's and touch panels:
Configure the devicetree to load the open source drivers: (make the following changes to /boot/config.txt)

dtoverlay=vc4-kms-v3d
ignore_lcd=1

Expected result
7" panel should be initialized using DSI commands sent using DSI1 on the 15way display connector
7" panel should show correctly display image frames.

Actual result:
Panel is not started correctly. Often the device is initialized with random vertical lines.
We see that the panel does get probed and in a version we have with extended vc4_dsi logging -> we see that the dsi sub-systems appear to be configured with the same settings (DSI1_CTL, DSI1_PHY, DSI1_PHY_AFEC0, etc) as a working device

dmesg is littered with errors:
[drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
Relevant parts of dmesg ?:

[    0.000000] Linux version 4.15.17-v7+ (ec2-user@ip-172-31-3-70) (gcc version 4.7.1 20120402 (prerelease) (crosstool-NG 1.15.2)) #7 SMP Wed Apr 18 18:56:41 UTC 2018
[    0.090320] raspberrypi-firmware soc:firmware: Attached to firmware from 2018-04-16 18:16
[    3.624797] vc4_hdmi 3f902000.hdmi: vc4-hdmi-hifi <-> 3f902000.hdmi mapping ok
[    3.647006] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4])
[    3.648643] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4])
[    3.684381] vc4-drm soc:gpu: failed to bind 3f700000.dsi (ops vc4_dsi_ops [vc4]): -517
[    3.687102] vc4-drm soc:gpu: master bind failed: -517
[    3.923917] vc4_hdmi 3f902000.hdmi: vc4-hdmi-hifi <-> 3f902000.hdmi mapping ok
[    3.930640] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4])
[    3.930877] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4])
[    3.936229] vc4-drm soc:gpu: bound 3f700000.dsi (ops vc4_dsi_ops [vc4])
[    3.936381] vc4-drm soc:gpu: bound 3f400000.hvs (ops vc4_hvs_ops [vc4])
[    3.936683] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.936913] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.937165] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops vc4_crtc_ops [vc4])
[    3.958831] vc4-drm soc:gpu: bound 3fc00000.v3d (ops vc4_v3d_ops [vc4])
[    3.960315] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
[    5.031745] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[    5.031755] vc4_dsi 3f700000.dsi: instat: 0x00000000
[    5.031868] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[    6.071732] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[    6.071742] vc4_dsi 3f700000.dsi: instat: 0x00000000
[    6.071822] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[    7.111729] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[    7.111737] vc4_dsi 3f700000.dsi: instat: 0x00000000
[    7.111817] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[    8.151737] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[    8.151747] vc4_dsi 3f700000.dsi: instat: 0x00000000
[    8.151825] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[    9.191730] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[    9.191738] vc4_dsi 3f700000.dsi: instat: 0x00000000
[    9.191818] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[   10.231732] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[   10.231741] vc4_dsi 3f700000.dsi: instat: 0x00000000
[   10.231819] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[   11.271730] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[   11.271738] vc4_dsi 3f700000.dsi: instat: 0x00000000
[   11.271816] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[   12.311727] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[   12.311735] vc4_dsi 3f700000.dsi: instat: 0x00000000
[   12.311816] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[   13.351736] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[   13.351746] vc4_dsi 3f700000.dsi: instat: 0x00000000
[   13.351835] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[   14.551728] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[   14.551736] vc4_dsi 3f700000.dsi: instat: 0x00000000
[   14.551817] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110
[   15.591729] vc4_dsi 3f700000.dsi: transfer interrupt wait timeout
[   15.591737] vc4_dsi 3f700000.dsi: instat: 0x00000000
[   15.591817] [drm:vc4_dsi_host_transfer [vc4]] *ERROR* DSI transfer failed, resetting: -110

Other information:
If we do not set: "ignore_lcd=1" ; then the firmware appears to initialize the panel and the vc4_dsi sub-system.
With this, the open source drivers try to setup the panel, but the DSI transactions fail (presumably - due to firmware taking interrupts, etc from vc4)
The kernel will continue to establish the video sub-system and the display works.

I suspect that there is a downstream resource which is not being configured/started for the vc4_dsi sub-system to work properly.

We've done what investigation we can to debug this - but have run out of ideas ;)

@JamesH65
Copy link
Contributor

I suspect this needs to be reporting on Eric Anholt's github tracker for vc4 kms - this is not something we currently deal with here.

@k-quigley
Copy link
Author

Thanks for the comment. I've been in touch with @anholt about this issue. He checked on his upstream kernel version and the panel seems to be functioning ok. On the rpi kernel it's not.
If I need to raise it somewhere else -> happy to do so.

@JamesH65
Copy link
Contributor

Hmmm. Not sure then. Whilst I often deal with the panel stuff, I don't use the kms driver at all, I'm all at the VC4 firmware level.

@k-quigley
Copy link
Author

k-quigley commented Apr 23, 2018

I dug into this a little more.... perhaps your knowledge of vc4_dsi and the firmware drivers might help us isolate what's going on. I enabled some extra vc4 register logs around the DSI writes. Here's the vc4 status before we write:

[ 12.301971] [drm] 0x0000 (DSI1_CTRL): 0x00002801
[ 12.301975] [drm] 0x0038 (DSI1_STAT): 0x00000000
[ 12.301980] [drm] 0x003c (DSI1_HSTX_TO_CNT): 0x00000000
[ 12.301985] [drm] 0x0040 (DSI1_LPRX_TO_CNT): 0x00ffffff
[ 12.301990] [drm] 0x0044 (DSI1_TA_TO_CNT): 0x000186a0
[ 12.301994] [drm] 0x0048 (DSI1_PR_TO_CNT): 0x000186a0
[ 12.301999] [drm] 0x0028 (DSI1_DISP0_CTRL): 0x0003101d
[ 12.302004] [drm] 0x002c (DSI1_DISP1_CTRL): 0x00000005
[ 12.302008] [drm] 0x0030 (DSI1_INT_STAT): 0x00000000
[ 12.302013] [drm] 0x0034 (DSI1_INT_EN): 0x00003fc0
[ 12.302018] [drm] 0x004c (DSI1_PHYC): 0x00550001
[ 12.302022] [drm] 0x0050 (DSI1_HS_CLT0): 0x04201028
[ 12.302027] [drm] 0x0054 (DSI1_HS_CLT1): 0x00008070
[ 12.302032] [drm] 0x0058 (DSI1_HS_CLT2): 0x000f4240
[ 12.302036] [drm] 0x005c (DSI1_HS_DLT3): 0x01a0e030
[ 12.302041] [drm] 0x0060 (DSI1_HS_DLT4): 0x00008040
[ 12.302046] [drm] 0x0064 (DSI1_HS_DLT5): 0x004c4b40
[ 12.302051] [drm] 0x0068 (DSI1_HS_DLT6): 0x1e061806
[ 12.302055] [drm] 0x006c (DSI1_HS_DLT7): 0x000186a0
[ 12.302060] [drm] 0x0070 (DSI1_PHY_AFEC0): 0xdb6c0777
[ 12.302065] [drm] 0x0074 (DSI1_PHY_AFEC1): 0x00000000
[ 12.302070] [drm] 0x008c (DSI1_ID): 0x00647369
[ 12.302074] [drm] 0x0088 (DSI1_PHY_FIFO_STAT): 0x00020002
[ 12.302079] [drm] 0x0078 (DSI1_TST_SEL): 0x00000000
[ 12.302083] [drm] 0x007c (DSI1_TST_MON): 0x00000000
[ 12.302088] [drm] 0x0080 (DSI1_PHY_TST1): 0x00647369
[ 12.302093] [drm] 0x0084 (DSI1_PHY_TST2): 0x00647369

When we make the write -> the DSI1_PHY_FIFO_STAT moves from 0x00020002 to 0x00020060

I don't have the traces to hand, but on 4.9.60 I was sure that around the write, I saw a corresponding change of state to DSI1_STAT (indicating that the HW block is doing something).

In the later versions -> this doesn't seem to happen. It's like some downstream or dependent HW is maybe not correctly configured, OR vc4_dsi is not properly enabled. Any ideas ?

@JamesH65
Copy link
Contributor

Hmm, nothing jumping out - I'd have to dig in to the DSI driver code on the VC4 to see how it compares. - from a DSI screen driver POV I just called the DSI driver and it does 'the right things'. I'll take a look.

@JamesH65
Copy link
Contributor

JamesH65 commented Apr 23, 2018

Something a bit odd - in the trace above the DSI1_PHY_FIFO_STAT register appears to be 0x88, however, according to the code I have, that's actually the DSI1 ID register, which is a RO register containing 0x64736931.

I'll need to cross reference against the kms driver or wherever this DSI driver is - to save time, do you know where the github for it is?

@JamesH65
Copy link
Contributor

JamesH65 commented Apr 23, 2018

Colleague just mentioned that there are known missing DT entries in this PR that you should probably merge in. Might help, might not, still doesn't explain why that STAT register appears to be wrong.

#2374

@JamesH65
Copy link
Contributor

Ah, its possible my docs are out of date and an extra register was added after the docs were finalised. No idea what that register does, but might not be an issue. So please try the PR referenced above to see if that fixes the problem.

@k-quigley
Copy link
Author

k-quigley commented Apr 23, 2018

Hi - the commit you mention here: #2374 is equivalent to the patch I listed above as the prerequisite:

Enable raspberrypi touchscreen driver in devicetree (e.g. anholt/linux@1d460b1)
anholt@d7fc047

This patch sets-up the needed I2C channels and triggers DT to load the 7" panel driver. We need that on top of the current "stock" 4.15 kernel so that the driver gets loaded.

@k-quigley
Copy link
Author

For the kernel version which these logs came from
The VCS_DSI driver is here: https://github.com/raspberrypi/linux/blob/rpi-4.15.y/drivers/gpu/drm/vc4/vc4_dsi.c
The panel driver is here: https://github.com/raspberrypi/linux/blob/rpi-4.15.y/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c

Please note: The panel driver has a patch (referenced at the top of the issue) to enable DSI transactions for the initialization: anholt/linux@1d460b1

@k-quigley
Copy link
Author

I've got some time this week to look into this. Is there anything else I can do to help, try, etc. Just let me know.

Has anyone else been able to reproduce this ?

@JamesH65
Copy link
Contributor

Can you compare the two kernel trees (Anholt, Pi) for any obvious differences in this area?

@k-quigley
Copy link
Author

@JamesH65 , sorry for the delay. I'm not in a position where I can get Eric's kernel to build and run in my environment... (kernel config issues, etc)... So it's difficult for me to check. I've done a visual comparison on the key areas -> but nothing springs out.

I would like to be able to verify that the DSI hardware is correctly powered ? Since the internal state machines don't seem to change when you write to the module, I'm wondering if there is a power or clock issue burred somewhere (like the power for the DSI block is not enabled). Is there anyway I can check this from the firmware ?

@k-quigley
Copy link
Author

Ok - I got to the bottom of the issue. A mix of devicetree changes against miss-matched configs (bcm2709_defconfig vs bcm2835_defconfig) needed to enable this properly. I have a patch set - which enables DeviceTree for the VC4 DSI encoder and provides a separate overlay to enable the 7" panel, based on 4.15.17 kernel version. I suspect any later kernels will need the same DT support added.

I only verified this in RPI 3 ModelB, with the 7" RPI panel.

Patch is attached here - for ease:

0001-Update-devicetree-to-enable-7-touchscreen-Panel.patch.txt

@JamesH65
Copy link
Contributor

@k-quigley Did you send this in as a Pull Request on our kernel tree? It will be more easily dealt with there.

@JamesH65 JamesH65 added the Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. label Jun 26, 2018
@anholt
Copy link
Contributor

anholt commented Jun 26, 2018

Enabling the DSI in the overlay in the current tree means that the DRM driver will fail to probe if the DSI panel is not present.

@boatbodger
Copy link

boatbodger commented Jul 2, 2018

I'm trying to bring up the Texas SN65DSI83 DSI to LVDS bridge chip from an R-Pi 3B, and I think I 'm nearl there - with very many thanks to anholt and quigley
I've made panel-texas-sn65dsi83.c (based on panel-raspberrypi-touchscreen.c) and got the DT more or less right. config.txt has ignore_lcd=1 and disable_touchscreen=1
Probe is being called, and the i2c bus is working (reading chip ID correctly, confirmed on a logic analyser), drm_panel_add() appears successful - dmesg | grep texas gives:
[ 10.217844] panel-texas-sn65dsi83 3f700000.dsi.0: Entering probe
[ 10.217852] panel-texas-sn65dsi83 3f700000.dsi.0: About to get i2c
[ 10.217899] panel-texas-sn65dsi83 3f700000.dsi.0: About to read bridge chip
[ 10.218543] panel-texas-sn65dsi83 3f700000.dsi.0: Bridge chip I2C probed OK.
[ 10.218553] panel-texas-sn65dsi83 3f700000.dsi.0: About to dsi_attach
[ 10.218583] driver: 'panel-texas-sn65dsi83': driver_bound: bound to device '3f700000.dsi.0'
[ 10.218681] bus: 'mipi-dsi': really_probe: bound device 3f700000.dsi.0 to driver panel-texas-sn65dsi83

However, 'enable' is not being called and, no packets are visible on the PHY
Can one of you help me work out what I need to do to 'enable' PHY activity? I bet it is something obvious...

@boatbodger
Copy link

boatbodger commented Jul 2, 2018

Update:

  1. I now realise 'enable' not not being called mainly means the bridge chip won't get set up - I can fix that later.
  2. Looking in dmesg in more detail I see the device attempts to bind, but then fails:
    [ 10.187673] bus: 'mipi-dsi': really_probe: bound device 3f700000.dsi.0 to driver panel-texas-sn65dsi83
    [ 10.187779] vc4-drm soc:gpu: bound 3f700000.dsi (ops vc4_dsi_ops [vc4])
    [ 10.187857] vc4-drm soc:gpu: binding vc4_dsi (ops vc4_dsi_ops [vc4])
    [ 10.187941] vc4-drm soc:gpu: failed to bind vc4_dsi (ops vc4_dsi_ops [vc4]): -19
    [ 10.187961] device: '3f700000.dsi.0': device_unregister
    [ 10.188016] bus: 'mipi-dsi': remove device 3f700000.dsi.0
    [ 10.189162] device: 'MAI': device_unregister
    [ 10.232090] vc4-drm soc:gpu: master bind failed: -19
    [ 10.232136] vc4-drm: probe of soc:gpu rejects match -19
    Which I think looks like a device-tree error - but I have to confess to being a bit confused by interplay between vc4, dsi, and the mutually pointing endpoints between the i2c stuff and the dsi stuff.
    Is there a post somewhere which would help me get my thinking clear on this?
    I have taken the liberty of attaching my device tree in case some kind soul can help!
    dt_from_fs.txt

@boatbodger
Copy link

I am now 99% certain my problem is that the DSI hardware is not powering up. The lane lines are floating.
Hardware is good, in that if I connect an 'official' display, it comes on.
Have you got any tips on debugging the power enabling side of the devicetree entries?
I have very carefully added the changes K Quigley has so kindly provided, but guess I'm still missing something.

@k-quigley
Copy link
Author

I encountered a similar issue. I worked out that the DSI HW wasn’t “active” since after a write to the control registers, nothing seemed to change. The device-tree was missing the entries which triggered the DSI logical blocks to be powered. Maybe the patchset I did – didn’t cover all the RPI HW/chipset possibilities ?

Here is the part of the patch which does this:

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e36c392a2b8f..17ad89b5b57f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -101,8 +101,10 @@
 
 &dsi0 {
 	power-domains = <&power RPI_POWER_DOMAIN_DSI0>;
+	status = "okay";
 };
 
 &dsi1 {
 	power-domains = <&power RPI_POWER_DOMAIN_DSI1>;
+	status = "okay";
 };


The display sub-system on the project we’re working on -> is on my list to come back to this week. I’ll post an update with my progress 

Hope this helps.

@mbt28
Copy link

mbt28 commented Aug 13, 2018

Hi,

I have built a circuit based on Texas SN65DSI83 DSI to LVDS chip however I havent wired yet.

Have you tried to use demo function of SN65DSI83? Is it working properly. I am planning to finalize wiring in a week or so.

Thanks

@boatbodger
Copy link

Hi mbt28,
Yes, the test function works fine - but remember you need ideally to provide an external reference oscillator if you are to display the test pattern without DSI clock coming in. I temporarily connected a 30MHz crystal oscillator module (being careful to use resistors to bring the level down to stay within the 1.8V supply rail.
Be very VERY careful to clamp the I2C lines. I have now 'killed' two of these chips and I'm 99% certain it was overvoltage (due to ringing) on the I2C lines. Put a low capacitance schottky on each line to "dump" any excess voltage to the 1.8V line, and make sure they go directly to a decoupling capacitor.
The chips are not cheap, and it's not all that easy desoldering and re-soldring them without damaging the PCB!
If you are driving the I2C from the R-Pi, then you'll need level shifters. I used a schottky diode and an NPN transistor on each line. Since the circuit below was drawn, I added two further schottkys to the 1v8 line:
image

@boatbodger
Copy link

boatbodger commented Aug 15, 2018

Hi k-quigley
Many thanks for your response - look forward to hearing further news.

Would you by any chance be able to send me a dump of your working flattened devicetree so I can compare with mine?
I think I have all the power patches in place, yet still the DSI is not coming up.
I have tried both with, and without enabling the overlay 'vc4-kms-v3d.
My driver is being probed.
I see the following events shortly after calling mipi_dsi_attach()
[ 16.873775] driver: 'panel-texas-sn65dsi83': driver_bound: bound to device '3f700000.dsi.0'
[ 16.873804] kobject: '3f700000.dsi.0' (9e1ef010): kobject_uevent_env
[ 16.873840] kobject: '3f700000.dsi.0' (9e1ef010): fill_kobj_path: path = '/devices/platform/soc/3f700000.dsi/3f700000.dsi.0'
[ 16.873938] bus: 'mipi-dsi': really_probe: bound device 3f700000.dsi.0 to driver panel-texas-sn65dsi83
[ 16.873981] vc4_dsi 3f700000.dsi: genpd_runtime_suspend()
[ 16.873997] vc4_dsi 3f700000.dsi: suspend latency exceeded, 3907 ns
[ 16.874100] DSI1: Power-off latency exceeded, new value 85469 ns
[ 16.874297] kobject: 'drivers' (9b21c680): kobject_add_internal: parent: 'panel_texas_sn65dsi83', set: ''
[ 16.874334] kobject: 'panel-texas-sn65dsi83' (9c322e80): kobject_uevent_env
[ 16.874349] kobject: 'panel-texas-sn65dsi83' (9c322e80): fill_kobj_path: path = '/bus/mipi-dsi/drivers/panel-texas-sn65dsi83'
And later I see repeated messages like this:
[ 84.465558] vc4_v3d 3fc00000.v3d: genpd_runtime_resume()
[ 84.532861] vc4_v3d 3fc00000.v3d: genpd_runtime_suspend()
[ 85.967029] vc4_v3d 3fc00000.v3d: genpd_runtime_resume()
[ 86.012888] vc4_v3d 3fc00000.v3d: genpd_runtime_suspend()
[ 87.467967] vc4_v3d 3fc00000.v3d: genpd_runtime_resume()
[ 87.542873] vc4_v3d 3fc00000.v3d: genpd_runtime_suspend()

@mbt28
Copy link

mbt28 commented Aug 15, 2018

Hi Boatbodger,

I am using TXS0102DCT for I2C level shifting. The schematic is like below. However I havent tried it yet. I bought 2 chips. Soldering of them was quite hard for me because it was the first time I have soldered something which is 0,5mm pitch. First 2 sides I soldered in horrible way but the other 2 are perfect.

image

I havent wired yet but I believe it wont work, most probably I damaged the bridge chip during soldering. I dont have an ocilator with me currently, I think I will bypass this feature and try to initialize display from RPI.

Following weeks I will be travelling, so I dont beleive I can work more. However if I can get result till Friday, I will take the screen with me to focus on kernel driver.

If it is possible, can you share the I2C level shifting and protection with more detail?

@boatbodger
Copy link

My current approach is this:
image
Remember, I2C is always "passive pull-up", so R1 (which is inside the R-Pi) will always try to pull the line to 3.3V, and R2 will always try to pull it to 1.8V
So now, when the R-Pi pulls the line low, D1 will pull down the line into the 1.8V device.
When the 1.8V device pulls the line low, it will switch on the transistor, which - in turn, pulls down the line into the 3.3V device.
Now when the line into the 3.3V device is "let go", the reverse capacitance in D1 has to charge up. D2 makes sure this is done via the 1.8V supply a and NOT by reverse biasing the protection diode on the 1.8V device. D1 and D2 both need to be low capacitance Schottky diodes with a low forward voltage.

Obviously you need two instances of the circuit above, one for I2c Clock, the other for I2c data.

Using a 'scope, I could see that without D2 in place, there were discernable spikes of well over a volt being generated back towards the 1.8V chip, and after a while, that blew it up (amazingly).

Although this circuit works well, I suspect the TI chip you found will be be a tidier solution, and I'll probably use that in the future. And yes, 0.5mm pin spacing is quite taxing, but with a 0.3mm bit, and 0.3mm solder, not entirely impossible, provided one has a good bench magnifier.

@k-quigley
Copy link
Author

@boatbodger please see below the flattened device tree from my Pi3 (Linux raspberrypi 4.15.17-v7+) with the changes enabled to run the Rpi7" display.

current_dt.txt

@k-quigley
Copy link
Author

For level shifting, we use an approach similar to this - for BiDirectional level shiters (available as IC's too)

https://hackaday.com/2016/12/05/taking-it-to-another-level-making-3-3v-and-5v-logic-communicate-with-level-shifters/

@llks
Copy link

llks commented Jan 31, 2019

I am planning to use the Raspberry Pi Model B to power up a MIPI display, TM050JDHG33, which use the driver IC ILI9881C. I would like to seek the opinion of enabling this display from the Raspberry Pi Model B, and can we apply the following work flow for this application?

a. Use the kernel v4.20.y code reference, panel-ilitek-ili9881c.c (https://github.com/raspberrypi/linux/blob/rpi-4.20.y/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c ) or panel-raydium-rm68200.c (https://github.com/raspberrypi/linux/blob/rpi-4.20.y/drivers/gpu/drm/panel/panel-raydium-rm68200.c ) as reference and put TM050JDHG33 ili9881 initialization code to newly created driver “panel-tm050jdhg33.c“

b. build the kernel with this driver and update to the system.

c. Configure the firmware to load this driver using the MIPI-DSI interface in the “config.txt”,

dtoverlay=vc4-kms-v3d
ignore_lcd=1

Anything else I need to do to enable this driver? Any suggestion?

@tdaniel22
Copy link

Has someone managed to make this work with the 4.19 kernel? I tried porting the DT entries without success.

@boatbodger
Copy link

boatbodger commented Jun 10, 2019

Hi tdaniel22,
To date, I've managed to make things work by spoofing the R-Pi into thinking it had an official display using a PIC to emulate the i2c transactions, with a separate kernel module acting purely as a bridge - i.e. kid the Pi firmware into making the DSI signal, then separately set up the TI bridge chip to convert the DSI to LVDS.
Happy to share my PIC code if you're into that kind of thing.

@boatbodger
Copy link

boatbodger commented Jun 10, 2019

@boatbodger please see below the flattened device tree from my Pi3 (Linux raspberrypi 4.15.17-v7+) with the changes enabled to run the Rpi7" display.

current_dt.txt
Hi k-quigley,
Thank you so much for sharing the fdt.
I am now re-visiting this subject after a hiatus of many months, and am using 4.19.46 kernel,
I have made tweaks to my overlay which make almost everything look right - in particular the power-domains entries - BUT your fdt includes an alias which I don't have, so...

  • can you tell me how the entry
    display0 = "/chosen/framebuffer@3eb79000";
    gets into the fdt?
  • Did your implementation require vc4 to be used? Is it necessary? (I'm not doing gaming!)
  • If so, did you have to make vc4 compiled-in, or would it work as a module? Some posts say it has to be compiled in, but I could not persuade make menuconfig to do that, even though I set drm to be compiled
  • On my kernel, when vc4 tries to load, dmesg shows several:
    vc4-drm soc:gpu: failed to bind 3f700000.dsi (ops vc4_dsi_ops [vc4]): -517
    and eventually:
    [drm:vc4_dsi_bind [vc4]] *ERROR* Failed to get DMA channel: -19
    I'm currently rebuilding the kernel with DMA-API debugging enabled, which may give me some clues but I'd very much appreciate your comments on the above.
    Thanks in advance

@k-quigley
Copy link
Author

k-quigley commented Jun 10, 2019 via email

@pelwell
Copy link
Contributor

pelwell commented Jun 10, 2019

can you tell me how the entry
display0 = "/chosen/framebuffer@3eb79000";
gets into the fdt?

That is added automatically by the firmware if it determines that /soc/fb is absent from (or disabled in) the Device Tree after applying overlays. This is likely to be as the result of using one of the vc4-*kms-v3d overlays, or of running an upstream kernel configuration.

@boatbodger
Copy link

Many thanks, Kevin and Phil.
I feel I must be sooooo close to getting this working.
In the dmesg dump below (40 lines), I have stripped out (what I believe to be) irrelevant device activity:
[ 4.179940] vc4_hdmi 3f902000.hdmi: ASoC: Failed to create component debugfs directory [ 4.183790] vc4_hdmi 3f902000.hdmi: vc4-hdmi-hifi <-> 3f902000.hdmi mapping ok [ 4.188271] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4]) [ 4.188541] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4]) [ 4.247932] vc4-drm soc:gpu: failed to bind 3f700000.dsi (ops vc4_dsi_ops [vc4]): -517 <other device messages from usbcore, brcmfmac> [ 4.268266] vc4-drm soc:gpu: master bind failed: -517 [ 4.270910] vc4_hdmi 3f902000.hdmi: ASoC: Failed to create component debugfs directory [ 4.272787] vc4_hdmi 3f902000.hdmi: vc4-hdmi-hifi <-> 3f902000.hdmi mapping ok [ 4.273852] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4]) [ 4.274090] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4]) [ 4.279060] vc4-drm soc:gpu: failed to bind 3f700000.dsi (ops vc4_dsi_ops [vc4]): -517 [ 4.280278] vc4-drm soc:gpu: master bind failed: -517 [ 4.398486] panel-texas-sn65dsi83 3f700000.dsi.0: Piglets! probe [ 4.398504] panel-texas-sn65dsi83 3f700000.dsi.0: About to get i2c [ 4.398517] Texas: node->phandle=127 [ 4.398533] Texas: client=dsi-lvds-panel [ 4.398538] Texas: Returning with a good result [ 4.398547] i2c 3-002c: About to get reset GPIO [ 4.398613] i2c 3-002c: gpio_dev ptr=9e3221b0 [ 4.398622] i2c 3-002c: Gpio 27 - About to do a timed reset [ 4.398637] i2c 3-002c: Drive low, result 0 [ 4.472066] i2c 3-002c: Drive high, result0 [ 4.472077] i2c 3-002c: Reset sequence done, sleeping for another 100ms <more messages from brcmfmac regarding v4l2> [ 4.482937] vc4_hdmi 3f902000.hdmi: ASoC: Failed to create component debugfs directory [ 4.491223] vc4_hdmi 3f902000.hdmi: vc4-hdmi-hifi <-> 3f902000.hdmi mapping ok [ 4.495185] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4]) [ 4.495421] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4]) [ 4.518390] vc4-drm soc:gpu: failed to bind 3f700000.dsi (ops vc4_dsi_ops [vc4]): -517 [ 4.519630] vc4-drm soc:gpu: master bind failed: -517 [ 4.642081] About to read bridge chip [ 4.642815] i2c 3-002c: Bridge chip I2C probed OK - sending setup. [ 4.682542] i2c 3-002c: About to dsi_attach [ 4.684944] vc4_hdmi 3f902000.hdmi: ASoC: Failed to create component debugfs directory [ 4.687932] vc4_hdmi 3f902000.hdmi: vc4-hdmi-hifi <-> 3f902000.hdmi mapping ok [ 4.689174] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops [vc4]) [ 4.689499] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops [vc4]) [ 4.690030] [drm:vc4_dsi_bind [vc4]] *ERROR* Failed to get DMA channel: mask:0001 chan:-19 [ 4.690127] vc4-drm soc:gpu: failed to bind 3f700000.dsi (ops vc4_dsi_ops [vc4]): -19 [ 4.691305] vc4-drm soc:gpu: master bind failed: -19
So what seems to be happening is the vc4 initially finds no panel and reports 517 i.e. EPROBE_DEFER. Once my driver is probed, it scribbles "Piglets" to the log - just 'cos that's easy to find - and we're seeing that.
From there, we can see my debug showing

  • discovery of the i2c device from the DSI device
  • discovery GPIO required to reset the bridge chip from the i2c device
  • Issuing the reset (confirmed with a 'scope)
  • Setting up the bridge chip (also confirmed)
  • Issue of the dsi_attach at 4.682 seconds,
  • then vc4 has another go at starting up and no longer returns EPROBE_DEFER,,but this time fails to acquire a DMA channel and gives up in disgust with ENODEV.
    So the question is why is the DMA request failing.
  • I've seen some other posts implying that some of the optional devices are gobbling up DMA channels, which are a scarce resource.
  • Other posts suggest one can see which DMAs are in use or free by looking at /sys/module/dma/... but on my installation that folder does not exist. There is a folder called dma under sys/devices/platform/soc/3f007000.dma which has references for channels 0 through 9, but I'm not sure how I can tell whether they are in use or not [hints welcome]
  • Other suggest that DMA channel 1 is reservice for the GPU - but if that were the case, surely the vc4 module should not need to be requesting a channel

If I use the pi3-disable-bt overlay, the DMA error disappears, but then we just get a couple more EPROBE_DEFER errors, all ultimately resulting in
[ 4.945104] vc4-drm soc:gpu: master bind failed: -517

Any hints on how I can further debug this?
Thanking you in advance...

@boatbodger
Copy link

boatbodger commented Jun 10, 2019

OK - the bind failure was due to a very well hidden error in the device tree (slight mis-placement of one of the two matching port {} statements).
Edit: this post originally had information which was wrong and potentially confusing - so I've deleted it.
I'm still seeing vc4 reporting interrupt timeout errors code -110, and occasionally vc4 seems unable to obtain a DMA channel.

@boatbodger
Copy link

I've determined that the transfer interrupt timeouts result from trying to set the DSI up directly from my driver, which turns out to be un-necessary (even though that is what panel-raspberrypi-touchscreen.c does).
The interface sometimes comes up without those calls, but quite often - particularly after a cold boot - the "unable to obtain DMA channel" happens, which stops the display from initialising.

@boatbodger
Copy link

boatbodger commented Jun 12, 2019

Today I sat down and carried out around 30 reboots - a mix of soft (sudo reboot) and hard (pull the power). I have attached a text file with extracts from dmesg output for half of them.
I notice that there is a direct correlation between the number of times the vc4 tries to probe the panel and fails with a -517 error, and whether or not it encounters a failure to acquire a DMA channel.

The number of -517's varies between zero and four.
With 0,1,2 or 3 -517's it acquires a DMA channel and everything starts up properly.
If there are four, it fails.
it is also noticeable that if the first -517 error occurs sooner in the boot-up it tends to 'run out of tries'.
I do need to fix this, as it will look really bad if the appliance I'm building 'sometimes boots up and sometimes doesn't'.
Do those of you with more experience believe this is likely to be something 'fixable' by better device-tree configuration, or is this more likely to need fixes to the vc4 driver?
good_bad_ugly.txt

@pelwell
Copy link
Contributor

pelwell commented Jun 12, 2019

Your symptoms suggest that something is claiming a DMA channel while probing and then failing to free it when the probe fails. After a few iterations it's leaked more channels than you have spare, so something fails.

That fact that you get different numbers of -517 (-EPROBE_DEFER) errors supports my theory that device probing order is essentially random. It's a sad fact that these errors are how probing is supposed to work (although the error messages should be suppressed), the idea being that by retrying previously deferred probes after each subsequent driver is loaded you will eventually get to a working system. Unless something is genuinely missing or broken, in which case it will just silently wait forever.

Seeing your errors jogged my memory of a suggestion that the bcm2835-sdhost driver had such a leak (it was fixed in other SD card drivers, but the downstream sdhost driver was missed). Indeed there was a leak there that I've just fixed in rpi-4.19.y. If you're up for building your own kernel you can try it out, or wait a day or two and it will be available via rpi-update (insert usual warnings).

Building your own may be the quickest route to a solution - if my patch doesn't solve it, add a WARN_ON(1); to the start of bcm2835_dma_xlateand bcm2835_dma_free and look for an imbalance in the callers.

@boatbodger
Copy link

boatbodger commented Jun 12, 2019

I already have the 4.19.46 source tree up and running, building "my" modules in tree, so would be very happy to try it out.
Thanks for the tip re adding some warn_on's. I'll do that and report back.
EDIT: Done that, and I think it confirms that there are repeated "acquires" during the probing cycles, without corresponding releases if EPROBE_DEFER is used - see attachment.
dmesg.txt

I've just been looking at the source of vc4_dsi.c, and can see that in vc4_dsi_bind(), it goes through collecting various resources (including DMA memory, a dma channel, an interrupt etc. etc.) There are many points where control is returned with the value -EPROBE_DEFER - without "giving them back".
No checks are made before acquisition to see if these resources were allocated in a previous attempt at the bind, as far as I can see (please bear in mind that whilst I'm an experienced programmer, I'm very new to kernel module programming so forgive me if I'm talking rubbish).

I'd be very grateful if you could help me with the 'protocol'/'etiquette' here. Would it be correct within the Linux ethos for me to have a go at "improving" this vc4_dsi code, or is that insulting to the original writer?

@pelwell
Copy link
Contributor

pelwell commented Jun 12, 2019

The Linux devs will take patches from anyone, but I suggest you start with a Pull Request here to get some quick, friendly feedback.

@boatbodger
Copy link

pelwell - Thank you for your encouragement and support I have made a Pull Request (I think - I'm very much a git newbie).
k-quigley - I think 'Fix DMA channel and memory leak in vc4 #3012' may help your panel to start up correctly every time. Mine does now.

@tdaniel22
Copy link

@boatbodger Sorry I have to admit I'm a bit confused; is this for the official 7" touchscreen or other DSI panels? I am interested in making the official panel work with the vc4-kms-v3d overlay, which I thought was the initial problem described in this issue.

@k-quigley
Copy link
Author

k-quigley commented Jun 13, 2019 via email

@boatbodger
Copy link

@tdaniel22
This thread is primarily about using non-Raspberry Pi DSI-attached devices (k-quigley's OP has ignore_lcd=1)
To do that, one has to use the vc4-kms-v3d overlay so far as I can tell - so there is perhaps some overlap with your needs, as for that overlay to work, the vc4 module has to work.

@tdaniel22
Copy link

@boatbodger Thanks for clarifying. I am currently using the vc4-fkms-v3d overlay with an official panel and it seems to be working fine. I assumed that fkms stands for fake-kms, and that it was a workaround for the non working vc4-kms-v3d overlay. Is my understanding correct, or am I inventing an issue here?

For context, I'm mostly interested in reducing boot times of an embedded system, and currently it takes around 5 seconds for the panel to light up on an already optimized buildroot system. I'm not sure whether the kms overlay would improve anything at all in this regard.

@boatbodger
Copy link

@tdaniel22 I believe the 'f' is short for firmware. IMHO if you're using the official display, using the standard settings - which means everything happens in the firmware - is likely to give you the shortest boot time - we're quite a way off topic here though, with all due respect.

@boatbodger
Copy link

@k-quigley I've submitted updated my earlier pull request in line with @pelwell's comments.
If you were able use that version for your tests, it would be much appreciated.

@boatbodger
Copy link

boatbodger commented Jun 14, 2019

@k-quigley I noticed that the display goes out irrecoverably if the screen saver/blanker kicks in.
A dmesg error of;
vc4_dsi 3f700000.dsi: Timeout waiting for DSI STOP entry: STAT 0x00020800
is reported.
For my usage, that initially wasn't a problem as the screen is meant to be on 24x7.
However, I need portrait mode. The old "display_lcd_rotate=1" does not work for a screen attached in this way (i.e. via the vc4 module), but I can achieve that result by using the xrandr commands.
However, when I do that, as part of the process of applying the transformation, it seems the decoder is disabled. This calls vc4_dsi_ulps(dsi, true), which triggers the DSI STOP error.
Are you also seeing this DSI lock-up after screen saver kicks in?
I can 'fudge' things by commenting out the call to vc4_dsi_ulps for the time being, but that's certainly not the right answer!
IMHO this is a separate issue, and one I'm unlikely to solve without detailed knowledge of the DSI register transactions - which I don't have.
FWIW this error occurred before I started hacking vc4_dsi.c - so I don't think its self-inflicted.

@k-quigley
Copy link
Author

k-quigley commented Jun 14, 2019 via email

@boatbodger
Copy link

I've 'scoped the clock lines on the DSI bus, and when i do a screen rotate they go absolutely wild.
During normal operation, the average DC level is about 200mV. The 1GHz clock is not visible on my 'scope (although I can pick it up on a spectrum analyser so I know it's there).
However the attached screen shot shows them intially flying up to about 0.8V for a varying period (about 40mS on this trace) then right up to about 1.2V for a few hundred microseconds before settling down to normal clock. I think this pulse is knocking out the TI bridge chip causing it to lose sync until it is given a hard reset (which happens during boot-up). The short section either end of the trace is the normal clock
20190615_000610
If I repeatedly switch between 'normal' and 'right' using the xrandr utility, I see variations on this theme. And sometimes the TI chip regains sync after one of these 'thumps'.
On Monday, I'll create a utility to allow me to independently send the TI bridge chip a re-init sequence and see if that restores the display after its been smashed. If it does, then I probably "just" need to make changes to the device driver to send the configuration sequence each time the .enable operation is called. Its all very crude, but it'll get me going again, hopefully.
Incidentally, I tried the vc4-fkms-v3d overlay, but that did not work at all.

@6by9
Copy link
Contributor

6by9 commented Jun 15, 2019

vc4-fkms-v3d is kernel vc4 v3d driver, but firmware DRM/KMS driver. If the firmware doesn't support your display (which for DSI means the 7" official one), then you won't get anything.

DSI (and CSI) do use a variety of signal levels depending on the mode (High Speed, or Low Power) they're in - that is normal operation. I don't recall off-hand the actual voltage levels used, but they'll be in the spec.

Using rotation from xrandr generally means using V3D to do the rotation, often as a second pass after it has been composed to memory. Other than stopping and restarting the pipeline, I don't see why it is any different to any other scenario.
(On some systems there may be an option within DRM/KMS to rotate planes by multiples of 90degrees, but that isn't an option with the current vc4-kms driver. Transpose has to be done as an extra pass within the hardware)

@boatbodger
Copy link

boatbodger commented Jun 15, 2019

Hi @6by9 - thanks for the useful input. Ideally, I'd rather not use xrandr, but instead, have vc4/kms/v3d come up prepared with the 90 degree rotation. I understand that lcd_rotate and display_rotate are not going to work from config.txt, but do you know if there are other ways to achieve this rotation - e.g. by device-tree overlays when using the vc4-kms-v3d with a panel?
Or - since I've written a specific device driver for my panel - is there a way of telling drm (and therefore v3d) at set-up time that the display is rotated? (I can't get away with setting the mode to 480 x 800 px, because the DSI output signals need to be 800 x 480 to drive the LVDS bridge chip correctly).
For the time being, I've managed to stabilise the system by sending the bridge chip setup again when the panel driver receives a .enable call which I guess is also a defensive way of handling things.

@6by9
Copy link
Contributor

6by9 commented Jun 17, 2019

The main vc4 composition hardware (the HVS) does not support transpose. However there is a dedicated hardware block (called the transposer) that does support it, and writes the output of the HVS back to memory.
Within the firmware, setting display_rotate=[1|3] makes composition a two step process - once to compose the screen image into a memory buffer via the transposer, and a second to then display that image.

The vc4-kms-v3d driver does have support for the transposer as a writeback connector, however I don't believe the DRM framework will put the two halves together for you.
See https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#writeback-connectors for documentation.

@boatbodger
Copy link

Thank you for that - useful stuff. I will revisit the subject armed with this knowledge when I next have some time.

@dl9pf
Copy link
Contributor

dl9pf commented Jul 12, 2019

What is the latest state here ? Aka if I use 4.19 - which dtb's and options in config.txt do I need to use for the 7inch ?

@6by9
Copy link
Contributor

6by9 commented Dec 9, 2020

Largely obsolete so going to close. Please request a reopen if you think there is anything still to discuss on this thread.

5.10 now has DSI support merged with an overlay for the Pi 7" DSI panel, and a fix for a register issue that meant only 1 and 4 lane modes would work.
#3985 has an example dtoverlay for an ILI9881 DSI panel. Others are now managing to bring up displays with the full KMS driver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator.
Projects
None yet
Development

No branches or pull requests

10 participants