Closed notro closed 9 years ago
Changing the usb driver removes the need to change dma-mapping.h:
- buf = dma_to_virt(&urb->dev->dev, urb->transfer_dma);
+ buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma);
Next step is to find out why urb->transfer_buffer (buf) sometimes is NULL. Because include/linux/usb.h indicates that it should always be set:
* @transfer_buffer: This identifies the buffer to (or from) which the I/O
* request will be performed unless URB_NO_TRANSFER_DMA_MAP is set
* (however, do not leave garbage in transfer_buffer even then).
* This buffer must be suitable for DMA; allocate it with
* kmalloc() or equivalent. For transfers to "in" endpoints, contents
* of this buffer will be modified. This buffer is used for the data
* stage of control transfers.
Ping @P33M about dma_to_virt and urb->transfer_dma
The rationale behind the urb->transfer_dma and urb->transfer_buffer is here:
http://lxr.free-electrons.com/source/include/linux/usb.h#L1315
Perhaps this function may be of use (and avoids void *
casts)
http://lxr.free-electrons.com/ident?i=usb_hcd_map_urb_for_dma
usb_hcd_map_urb_for_dma
Usb core calls this function.
I have tracked down the issue to control messages that have no buffer. And clearly the new value that dwc_otg_urb_enqueue assignes to buf is wrong:
[ 5.777776] usb_control_msg: data= (null), size=0
[ 5.807121] usb_hcd_submit_urb: map and enqueue
[ 5.837748] usb_hcd_map_urb_for_dma: buf= (null), len=0, sgs=0, URB_NO_TRANSFER_DMA_MAP=0
[ 5.867765] usb_endpoint_xfer_control: uses_pio_for_control=0, uses_dma=1, HCD_LOCAL_MEM=0
[ 5.900545] urb->setup_dma=0x5afafbe0, urb->transfer_dma=0x00000000
[ 5.933451] usb 1-1: dwc_otg_urb_enqueue: buf is NULL, new buf=80000000, urb->transfer_dma=0x00000000
So I removed the (if clause and) statement: buf = dma_to_virt(...)
[ 6.437742] usb 1-1.4: dwc_otg_urb_enqueue: buf is NULL, new buf= (null), urb->transfer_dma=0x00000000
And no immediate ill effects. Network and keyboard is working.
@P33M comment?
I hadn't fully surfaced when I wrote the previous post, just to be clear: urb->transfer_buffer (buf) might be used as-is (no need to use dma_to_virt).
I have looked at all the places where transfer_dma is used, looking for situations where transfer_buffer might not be set. Since this is what the comment in dwc_otg_urb_enqueue() would indicate.
I found this drivers/usb/isp1760/isp1760-hcd.c (code is pre 2011):
1403 if (!urb->transfer_buffer && urb->transfer_buffer_length) {
1404 /* XXX This looks like usb storage / SCSI bug */
1405 dev_err(hcd->self.controller,
1406 "buf is null, dma is %08lx len is %d\n",
1407 (long unsigned)urb->transfer_dma,
1408 urb->transfer_buffer_length);
1409 WARN_ON(1);
1410 }
transfer_buffer is also set to NULL in usb_sg_init() if scatter/gather is used. But drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c expressively disables this:
int hcd_init(dwc_bus_dev_t *_dev)
{
[...]
hcd->self.sg_tablesize = 0;
So to stay safe, maybe something like this:
if (hcd->self.uses_dma && !buf && urb->transfer_buffer_length) {
buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma);
dev_warn_once(&urb->dev->dev,
"USB transfer_buffer was NULL, will use __bus_to_virt(%pad)=%p\n",
&urb->transfer_dma, buf);
}
__bus_to_virt might not work correctly on ARCH_BCM2835, so I would like to limit it's use.
@anholt has made a firmware driver for accessing properties through the just accepted mailbox driver: [PATCH 2/3 v2] ARM: bcm2835: Add the Raspberry Pi firmware driver I took that driver and made it work with drivers/mailbox/bcm2708-vcio.c. The patch to do this is quite small: https://gist.github.com/notro/80347b194004109ca572
Included in that patch is a way to set Revision (/proc/cpuinfo) for ARCH_BCM2835, and to turn on USB power.
The patched firmware driver can also be used without Device Tree. I will make a PR when the firmware driver is accepted in mainline.
There is also a new Device Tree property to set Serial (/proc/cpuinfo) in linux-next: ARM: 8355/1: arch: Show the serial number from devicetree in cpuinfo I will pick this up later.
It seems odd to use the property interface to query the board revision since it is already available from DT as "/system/linux,revision", which is set by the firmware.
Re: serial number - Does this mean they are abandoning "/system/linux,serial", which is also set by the firmware?
I had forgotten about those properties entirely. Yes, it's better/faster to use "/system/linux,revision".
There was an attempt to get system_rev from DT: [PATCH v2 1/2] arm: devtree: Set system_rev from DT revision http://lists.infradead.org/pipermail/linux-arm-kernel/2015-February/326534.html
Does this mean they are abandoning "/system/linux,serial"
I don't know who you refer to as they, but the property is non-standard. So keeping it would mean carrying a kernel patch to read it.
Is there a reason why you didn't include i2c-bcm2835 in this list? I'm not asking you to add it, but it would be useful for us on the Compute Module which needs more flexible pin configuration, and I want to make sure I haven't missed a gotcha that has already occurred to you.
When I made the list I looked at moving MACH_BCM2708 devices to DT, and i2c-bcm2835 isn't used here. Then I expanded focus to include ARCH_BCM2835 and i2c-bcm2835 is already used there. That's why the driver hasn't shown up in this issue.
I know there have been some changes to i2c-bcm2708 that haven't gone into mainline. I don't know the details, except that one of the changes broke "large" transfers: #865 I have very little experience with i2c.
I'm going to do onboard audio now. But I'm not sure where to put the DT devices. Should I put them in bcm2708_common.dtsi and have them enabled by default? Should they be placed under the sound node? Should each device have a label perhaps?
audio@0 {
compatible = "brcm,bcm2835-audio";
};
audio@1 {
compatible = "brcm,bcm2835-audio";
};
audio@2 {
compatible = "brcm,bcm2835-audio";
};
audio@3 {
compatible = "brcm,bcm2835-audio";
};
audio@4 {
compatible = "brcm,bcm2835-audio";
};
audio@5 {
compatible = "brcm,bcm2835-audio";
};
audio@6 {
compatible = "brcm,bcm2835-audio";
};
audio@7 {
compatible = "brcm,bcm2835-audio";
};
I can't put them inside the sound node.
Why?
It's because of_platform_populate->of_platform_bus_create skips nodes that doesn't have a compatible property. And sound doesn't have one.
I wonder, could we use a DT property to specify the number of channels? This way we would only need one DT device, and this could be the sound node itself.
What about this solution: https://gist.github.com/notro/dafa5f7f29aa237113b1
Device Tree:
sound: sound {
compatible = "brcm,bcm2835-audio";
channels = <8>;
};
I think that isn't going to work in the general case, because that slot has been used for external audio card drivers:
fragment@0 {
target = <&sound>;
__overlay__ {
compatible = "hifiberry,hifiberry-dac";
i2s-controller = <&i2s>;
status = "okay";
};
};
What I have done for other audio platform devices is to place them at the top level, e.g. from hifiberry-dac-overlay.dts:
fragment@2 {
target-path = "/";
__overlay__ {
pcm5102a-codec {
#sound-dai-cells = <0>;
compatible = "ti,pcm5102a";
status = "okay";
};
};
};
but it would be nice to find a better way.
Is it just me or is the "sound" node poorly documented?
Ok, so sound is taken. After a few minutes of looking around, sound seems to be a "connection" node:
sound {
compatible = "nvidia,harmony-sound";
i2s-controller = <&i2s1>;
i2s-codec = <&wm8903>;
};
};
..., and the sound node
represents not a device, but rather how other devices are connected
together to create the audio subsystem.
What about this?
/ {
[...]
alsa: alsa {
compatible = "brcm,bcm2835-audio";
channels = <8>;
};
@popcornmix what do you think about my approach? https://gist.github.com/notro/dafa5f7f29aa237113b1
Testing
This works for me on ARCH_BCM2835:
$ speaker-test -c2 -t wav
But this hangs (working fine on a standard kernel):
$ omxplayer /usr/share/scratch/Media/Sounds/Vocals/Singer2.wav
Audio codec pcm_s16le channels 1 samplerate 11025 bitspersample 16
Subtitle count: 0, state: off, index: 1, delay: 0
Nothing happens
$ ps as
[...]
2256 ? S 0:00 [VCHIQka-0]
2480 ? Ss 0:00 sshd: pi [priv]
2482 ? S 0:00 sshd: pi@pts/0
2483 pts/0 Ss 0:01 -bash
2501 pts/0 S+ 0:00 /bin/bash /usr/bin/omxplayer /usr/share/scratch/Media/Sounds/Vocals/Singer2.wav
2507 ? Ss 0:00 dbus-daemon --fork --print-address 5 --print-pid 6 --session
2510 pts/0 Sl+ 0:00 /usr/bin/omxplayer.bin /usr/share/scratch/Media/Sounds/Vocals/Singer2.wav
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2529 pi 20 0 4676 2448 2092 R 1.0 0.5 0:00.23 top
2510 pi 20 0 102m 10m 9652 S 0.3 2.5 0:02.22 omxplayer.bin
Ctrl-C doesn't stop omxplayer. But killall does. Nothing in the kernel log.
Then without rebooting I try speaker-test again, but now this hangs also:
$ speaker-test -c2 -t wav
speaker-test 1.0.25
Playback device is default
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Ctrl-C works.
Kernel log:
$ dmesg
[46206.371564] vc_vchi_audio_init:295 vc_vchi_audio_init: failed to open VCHI service connection (status=-1)
[46206.371612] vc_vchi_audio_init:308 vc_vchi_audio_init: closing 0: (null)
[46206.371628] vc_vchi_audio_init:314 vc_vchi_audio_init: error
[46206.371642] bcm2835_audio_open_connection:406 bcm2835_audio_open_connection: failed to initialize audio service
omxplayer doesn't use alsa. If it is is hanging then either something is hosed (e.g. vchiq is not reliable), or the previous failed alsa use has killed the GPU in some way.
Does omxplayer work from a clean boot?
Does omxplayer work from a clean boot?
Not with the ARCH_BCM2835 kernel. Can I turn on some debug output in omxplayer? Would it help to turn on some logging in /sys/kernel/debug/vchiq/log?
omxplayer -g
$ cat omxplayer.log
13:06:58 T:438508298 DEBUG: DllBcm: Using omx system library
13:06:58 T:438516269 DEBUG: DllOMX: Using omx system library
13:06:58 T:438519176 DEBUG: DllAvFormat: Using libavformat system library
13:06:58 T:438535420 DEBUG: DBus connection succeeded
13:06:58 T:438543856 DEBUG: Keyboard: DBus connection succeeded
13:06:58 T:438544595 DEBUG: OMXThread::Create - Thread with id -1304312768 started
13:06:58 T:438545057 DEBUG: DllAvUtilBase: Using libavutil system library
13:06:58 T:438545307 DEBUG: DllAvCodec: Using libavcodec system library
13:06:58 T:438545493 DEBUG: DllAvFormat: Using libavformat system library
13:06:58 T:438809418 WARNING: main - Ignoring video in audio filetype:/usr/share/scratch/Media/Sounds/Vocals/Singer2.wav
13:06:58 T:438818900 DEBUG: COMXCoreComponent::Initialize OMX.broadcom.clock input port 80 output port 81 m_handle 0x204a040
13:06:58 T:438820218 DEBUG: OMXClock::OMXStop
13:06:58 T:438821038 DEBUG: OMXClock::OMXSetSpeed(0.00) pause_resume:1
13:06:58 T:438822412 DEBUG: OMXThread::Create - Thread with id -1312701376 started
13:06:58 T:438823278 DEBUG: DllAvUtilBase: Using libavutil system library
13:06:58 T:438823554 DEBUG: DllAvCodec: Using libavcodec system library
13:06:58 T:438823737 DEBUG: DllAvFormat: Using libavformat system library
13:06:58 T:438823912 DEBUG: DllAvUtilBase: Using libavutil system library
13:06:58 T:438824095 DEBUG: DllAvCodec: Using libavcodec system library
13:06:58 T:438824254 DEBUG: DllAvFormat: Using libswresample system library
13:06:58 T:438825180 INFO: COMXAudioCodecOMX::GetChannelMap - FFmpeg reported 1 channels, but the layout contains 0 ignoring
13:06:58 T:438825538 DEBUG: DllAvUtilBase: Using libavutil system library
13:06:58 T:438825747 DEBUG: COMXAudio::SetCodingType OMX_AUDIO_CodingPCM
13:06:58 T:438826042 INFO: CPCMRemap: I channel map: CE
13:06:58 T:438826258 DEBUG: CPCMRemap: Mapping mono audio to front left and front right
13:06:58 T:438826525 INFO: CPCMRemap: O channel map: FL,FR
13:06:58 T:438826723 DEBUG: CPCMRemap: Downmix normalization is disabled
13:06:58 T:438826889 DEBUG: CPCMRemap: Mapping mono audio to front left and front right
13:06:58 T:438827171 DEBUG: CPCMRemap: FL = CE(0.707107)
13:06:58 T:438827470 DEBUG: CPCMRemap: FR = CE(0.707107)
13:06:58 T:438835967 DEBUG: COMXCoreComponent::Initialize OMX.broadcom.audio_decode input port 120 output port 121 m_handle 0x204a200
13:06:58 T:438844965 DEBUG: COMXCoreComponent::AllocInputBuffers component(OMX.broadcom.audio_decode) - port(120), nBufferCountMin(4), nBufferCountActual(16), nBufferSize(32768), nBufferAlignmen(16)
13:06:58 T:438863315 DEBUG: COMXAudio::Initialize Input bps 16 samplerate 11025 channels 1 buffer size 66150 bytes per second 22050
13:06:58 T:438863672 DEBUG: pcm->direction : input
13:06:58 T:438863862 DEBUG: pcm->nPortIndex : 0
13:06:58 T:438864020 DEBUG: pcm->eNumData : 0
13:06:58 T:438864190 DEBUG: pcm->eEndian : 1
13:06:58 T:438864364 DEBUG: pcm->bInterleaved : 1
13:06:58 T:438864522 DEBUG: pcm->nBitPerSample : 16
13:06:58 T:438864681 DEBUG: pcm->ePCMMode : 0
13:06:58 T:438864854 DEBUG: pcm->nChannels : 1
13:06:58 T:438865012 DEBUG: pcm->nSamplingRate : 11025
13:06:58 T:438865175 DEBUG: OMX_AUDIO_ChannelCF
13:06:58 T:438865354 DEBUG: COMXAudio::Initialize device omx:local passthrough 0 hwdecode 0
13:06:58 T:438866228 DEBUG: OMXThread::Create - Thread with id -1322654656 started
13:06:58 T:438866688 NOTICE: OMXClock using audio as reference
13:06:58 T:438867693 DEBUG: OMXClock::OMXReset audio / video : 1 / 0 wait mask 0->1 state : 2->1
13:06:58 T:438869532 DEBUG: Popped message member: NameAcquired interface: org.freedesktop.DBus type: 4 path: /org/freedesktop/DBus
13:06:58 T:438870938 WARNING: Unhandled dbus message, member: NameAcquired interface: org.freedesktop.DBus type: 4 path: /org/freedesktop/DBus
13:06:58 T:438872012 DEBUG: Normal M:0 (A:-4503599627370496 V:0) P:1 A:0.00 V:0.00/T:0.20 (0,0,0,1) A:0% V:0% (0.00,28.26)
13:06:58 T:438873815 INFO: CDVDPlayerAudio::Decode dts:0 pts:0 size:4096
13:06:58 T:438877465 DEBUG: COMXAudioCodecOMX::Decode(0x205f4d8,4096) format=1(1) chan=1 samples=2048 size=4096 data=0x2060500,(nil),(nil),(nil),(nil),(nil),(nil),(nil)
13:06:58 T:438877972 DEBUG: COMXAudioCodecOMX::GetData size=4096/4096 line=4096/4096 buf=0x2061508, desired=32768
13:06:58 T:438878217 INFO: CDVDPlayerAudio::Decode dts:185760 pts:185760 size:4096
13:06:58 T:438878682 INFO: CDVDPlayerAudio::Decode dts:371519 pts:371519 size:4096
13:06:58 T:438879184 INFO: CDVDPlayerAudio::Decode dts:557279 pts:557279 size:4096
13:06:58 T:438879637 INFO: CDVDPlayerAudio::Decode dts:743039 pts:743039 size:4096
13:06:58 T:438880041 INFO: CDVDPlayerAudio::Decode dts:928798 pts:928798 size:4096
13:06:58 T:438880483 INFO: CDVDPlayerAudio::Decode dts:1114558 pts:1114558 size:4096
13:06:58 T:438881053 INFO: CDVDPlayerAudio::Decode dts:1300317 pts:1300317 size:4096
13:06:58 T:438881847 DEBUG: COMXAudio::Decode ADec : setStartTime 0.000000
..., and the sound node represents not a device, but rather how other devices are connected together to create the audio subsystem.
I found that documentation, and although it is a reasonable statement I didn't find the reality lives up to it. What it seems to be is a place to instantiate a driver for a single audio system, made up of a number of codec and Digital Audio Interconnect devices. This works fine provided you have only one.
Although there are existing overlays that use "/sound" as their node, I am open to changing them if we can come up with a better solution. It would mean synchronising changes of kernel and DTB/overlay, but it wouldn't be the first time.
Things that you (or I) could try:
ARM-side VCHIQ logging:
sudo mount -t debugfs nodev /sys/kernel/debug
sudo chmod a+rwx /sys/kernel/debug
# Higher level, with some message content
sudo sh -c "echo info >/sys/kernel/debug/vchiq/log/msg"
# Low level, no message content
sudo sh -c "echo info >/sys/kernel/debug/vchiq/log/core"
# Low level, probably too verbose
sudo sh -c "echo trace >/sys/kernel/debug/vchiq/log/core"
# For user-space interactions
sudo sh -c "echo trace >/sys/kernel/debug/vchiq/log/arm"
Output available via dmesg.
VC-side VCHIQ logging:
# Higher level, with some message content
vcgencmd vcos log set vchiq_msg info
# Low level, no message content
vcgencmd vcos log set vchiq_core info
# Low level, probably too verbose
vcgencmd vcos log set vchiq_core trace
Output available via sudo vcdbg log msg
If you bear in mind that the protocol is symmetric you will understand that there is a lot of duplication between the two sides. I would suggest starting with
vcgencmd vcos log set vchiq_core info
sudo sh -c "echo trace >/sys/kernel/debug/vchiq/log/arm"
and seeing where that gets you.
This is my understanding of how devices are collected from DT:
static void __init bcm2708_dt_init(void)
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
of_default_bus_match_table
27 const struct of_device_id of_default_bus_match_table[] = {
28 { .compatible = "simple-bus", },
29 #ifdef CONFIG_ARM_AMBA
30 { .compatible = "arm,amba-bus", },
31 #endif /* CONFIG_ARM_AMBA */
32 {} /* Empty terminated list */
33 };
of_platform_bus_create() is called on all root node children. If there is no compatible property, that node is skipped. If compatible is not in _of_default_bus_matchtable, it does not look at child nodes. But on the soc node (simple-bus), it will continue to collect child devices inside that node (of_match_node).
414 dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
415 if (!dev || !of_match_node(matches, bus))
416 return 0;
417
418 for_each_child_of_node(bus, child) {
419 pr_debug(" create child: %s\n", child->full_name);
420 rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);
421 if (rc) {
422 of_node_put(child);
423 break;
424 }
425 }
But what about SPI devices inside the SPI controller node? SPI core adds the child devices as SPI devices using of_register_spi_devices when the SPI master is registered.
AFAICT our current use of the sound node is how it's meant to be used. The driver sets up a connection between the various sound components.
I have looked at the sound node drivers in sound/soc/bcm/ and they are almost identical. Maybe they could be merged into one driver and the differences be expressed as DT properties? And if something can't be expressed as a property, it could have a compatible string for that setup adding the special function that is needed.
Back to alsa, we could have this unified sound component driver also run of_platform_populate(NULL, NULL, NULL, NULL) on the sound node to add the alsa child node it contains. Making this work:
sound: sound {
alsa: alsa {
compatible = "brcm,bcm2835-audio";
channels = <8>;
};
};
I'm not sure if this kosher though since sound is not a bus, so maybe we should just keep the alsa node a sibling to the sound node.
Our multichannel VPU+PWM ALSA driver is independent of any external sound card, and it is the closest we have to an SOC sound component (the I2S driver also sort-of qualifies, and that is instantiated in /soc). Having to make all sound card drivers aware of the possible existence of this ALSA component seems wrong. ALSA seems capable of pulling together components from multiple entities at the level of sound cards, so why should we have to force them into multiple mutually exclusive artificial hierarchies in this way?
I would say that this PWM ALSA driver should either: a) be the root node of the sound hierarchy, one which can cause up to 8 VPU+PWM output devices to be added, and that calls of_platform_populate for any child nodes, or b) there should be yet another driver that exists solely to call of_platform_populate on all child nodes.
b) is conceptually cleaner, but seems like overkill. As the common element to all 2835-based systems (with Pi firmware), bcm2835-audio is a good candidate to be a parent for optional sound cards, so I prefer option a) (if it can be made to work).
For example:
sound: sound {
compatible = "brcm,bcm2835-audio";
channels = <8>; // We could change this name to something more descriptive, e.g. "brcm,pwm-channels"
status = "okay";
hifiberry-dac {
compatible = "hifiberry,hifiberry-dac";
i2s-controller = <&i2s>;
status = "okay";
};
pcm5102a-codec {
#sound-dai-cells = <0>;
compatible = "ti,pcm5102a";
status = "okay";
};
};
To disable the PWM output, set channels to 0.
Having to make all sound card drivers aware of the possible existence of this ALSA component seems wrong.
This was not my intention. I was thinking of unifying the "sound connection drivers" (ex. hifiberry_dac) into one driver which could then scan for devices.
I have spent some time looking at this and the sound node doesn't seem to be a special kind of node. 'sound' is just the preferred name for the sound device/card node. And this node can be quite complex on SoC's.
Reading http://devicetree.org/SoC_Audio more closely:
A top-level, virtual "sound" node to represent each ALSA (or other OS audio infrastructure) "card"
I understand this as one sound node per card. We have one onboard pwm card and one possible external card that uses i2s. Two sound devices/cards.
So I suggest we continue to use the sound node as we do now, and add the alsa node as a sibling:
/* Onboard audio */
audio: audio {
compatible = "brcm,bcm2835-audio";
brcm,pwm-channels = <8>;
};
/* External sound card */
sound: sound {
};
A stripped down simple-card could be used as a template for a unified virtual sound driver if that is desireable:
It could have been used as a replacement for hifiberry_amp and rpi-dac if it wasn't for their use of snd_soc_dai_set_bclk_ratio().
Yes, reading that brief guide again I think you are right. How messy though, with no container and no naming convention.
A more complete unified driver would need a way of representing ALSA volume controls, switches, power controls and LEDs using DT - it's no surprise that simple-card sticks to the digital domain with no gain controls - but it would be very satisfying to delete those drivers.
Let's go with your proposal above - "audio" and "sound" as siblings.
I don't have vc-mem yet, so I'll wait with omxplayer problem until I have gotten vc-mem in place. I can't imagine that the problem has anything to do with DT support in the sound driver. So I'll proceed and make a PR.
This is the ARM side trace when starting omxplayer: https://gist.github.com/notro/60e978bde75f6ad9b6de
If you only have access to ARM-side logging then you should enable a bit more of the ARM-side VCHIQ logging. These two
sudo sh -c "echo info >/sys/kernel/debug/vchiq/log/arm"
sudo sh -c "echo info >/sys/kernel/debug/vchiq/log/core"
are probably sufficient, since the previous log didn't show any abnormal termination.
Should I put the audio node in bcm2708_common.dtsi
disabled and then enable it in bcm2708-rpi*.dts
, or should I just put it directly in bcm2708-rpi*.dts
?
Put it in bcm2708_common.dtsi
- it is a feature common to BCM2835 and BCM2836, even if it isn't used.
The logging doesn't show any obvious errors, just an absence of data arriving. Annoyingly the logging level required to see arriving data is "trace", whereas for outbound data it is only "info". I've just pushed a patch that changes the logging level for inbound data to "info", for future cases.
Fortunately the test fails quickly, so lets just up the levels one more time:
sudo sh -c "echo trace >/sys/kernel/debug/vchiq/log/arm"
sudo sh -c "echo info >/sys/kernel/debug/vchiq/log/msg"
The interesting thread in the log is the DISP service, in that the final message from it goes unanswered. Annotating the trace with a bit of protocol decoding gives:
[ 1435.167092] vchiq: Sent: 00000000: 08 00 00 00 display_open
[ 1435.167116] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:8
[ 1435.167259] vchiq: Rcvd Msg DATA(5) from DISP s:5 d:2 len:4
[ 1435.167284] vchiq: Rcvd: 00000000: 00 00 00 10 ....
[ 1435.173698] vchiq: Sent: 00000000: 0e 00 00 00 display_get_info
[ 1435.173721] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:8
[ 1435.173863] vchiq: Rcvd Msg DATA(5) from DISP s:5 d:2 len:20
[ 1435.173897] vchiq: Rcvd: 00000000: 00 00 00 00 d0 02 00 00 e0 01 00 00 00 00 00 00 ................
[ 1435.174773] vchiq: Sent: 00000000: 0f 00 00 80 display_close
[ 1435.174795] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:8
[ 1435.278515] vchiq: Sent: 00000000: 08 00 00 00 display_open
[ 1435.278538] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:8
[ 1435.278686] vchiq: Rcvd Msg DATA(5) from DISP s:5 d:2 len:4
[ 1435.278726] vchiq: Rcvd: 00000000: 00 00 00 10 ....
[ 1435.280477] vchiq: Sent: 00000000: 10 00 00 00 update_start
[ 1435.280500] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:8
[ 1435.280633] vchiq: Rcvd Msg DATA(5) from DISP s:5 d:2 len:4
[ 1435.280657] vchiq: Rcvd: 00000000: 6f 00 00 40 o..@
[ 1435.282306] vchiq: Sent: 00000000: 13 00 00 00 element_add
[ 1435.282343] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:108
[ 1435.282485] vchiq: Rcvd Msg DATA(5) from DISP s:5 d:2 len:4
[ 1435.282509] vchiq: Rcvd: 00000000: 01 0c 00 20 ...
[ 1435.283749] vchiq: Sent: 00000000: 12 00 00 00 update_submit_sync
[ 1435.283771] vchiq: Sent Msg DATA(5) to DISP s:2 d:5 len:8
This show that there is no response to the update_submit_sync. VCHIQ knows nothing of the dispserve protocol, and all replies are sent in the same way.
There are two likely explanations: 1) The underlying update_submit_sync call never completes, so the VPU never tries to send a reply. 2) For some reason all VCHIQ traffic from the VPU have ceased, and that could also be because the transmissions aren't getting through.
As a general test of VCHIQ, try running vchiq_test -p
, verifying that it runs all the way to:
ping (size 4088, 1000 async, 1000 oneway) -> 241749.953125us
before stopping.
If that passes, we can rule out case 2) by adding some background traffic:
while true; do vcgencmd version; sleep 1; done
With this running, restart the test with the same logging as before and we'll see how the results differ.
$ sudo sh -c "echo trace >/sys/kernel/debug/vchiq/log/arm"
$ sudo sh -c "echo info >/sys/kernel/debug/vchiq/log/msg"
$ sudo dmesg -C
$ vchiq_test -p
Ping test - service:echo, iters:1000, version 3
^C
$
dmesg: https://gist.github.com/notro/1a234a49512f63cf25d8
I'll do vc-mem now. But I would like to boot directly from the VC bootloader without u-boot. This is because vc-mem gets it's parameters from the kernel commandline.
For this I need USB power turned on. I see 2 solutions:
Interesting log. It looks as though it just ground to a halt after a few pings.
While ping_test is stalled, can you capture the output from cat /dev/vchiq
?
$ cat /dev/vchiq
State 0: CONNECTED
tx_pos=1f0(@dc87a1f0), rx_pos=1a0(@dc85a1a0)
Version: 8 (min 3)
Stats: ctrl_tx_count=4, ctrl_rx_count=4, error_count=0
Slots: 30 available (29 data), 0 recyclable, 0 stalls (0 data)
Platform: 2835 (VC master)
Local: slots 34-64 tx_pos=1f0 recycle=1f
Slots claimed:
DEBUG: SLOT_HANDLER_COUNT = 29(1d)
DEBUG: SLOT_HANDLER_LINE = 2041(7f9)
DEBUG: PARSE_LINE = 2016(7e0)
DEBUG: PARSE_HEADER = -595222128(dc85a190)
DEBUG: PARSE_MSGID = 84045824(5027000)
DEBUG: AWAIT_COMPLETION_LINE = 778(30a)
DEBUG: DEQUEUE_MESSAGE_LINE = 940(3ac)
DEBUG: SERVICE_CALLBACK_LINE = 357(165)
DEBUG: MSG_QUEUE_FULL_COUNT = 0(0)
DEBUG: COMPLETION_QUEUE_FULL_COUNT = 0(0)
Remote: slots 2-32 tx_pos=1a0 recycle=1f
Slots claimed:
2: 24/23
DEBUG: SLOT_HANDLER_COUNT = 28(1c)
DEBUG: SLOT_HANDLER_LINE = 1844(734)
DEBUG: PARSE_LINE = 1820(71c)
DEBUG: PARSE_HEADER = 1533682144(5b6a21e0)
DEBUG: PARSE_MSGID = 83886119(5000027)
DEBUG: AWAIT_COMPLETION_LINE = 0(0)
DEBUG: DEQUEUE_MESSAGE_LINE = 0(0)
DEBUG: SERVICE_CALLBACK_LINE = 0(0)
DEBUG: MSG_QUEUE_FULL_COUNT = 0(0)
DEBUG: COMPLETION_QUEUE_FULL_COUNT = 0(0)
Instance dadbc800: pid 2297, connected, completions 0/16
Service 0: OPEN (ref 2) 'echo' remote 39 (msg use 23/3840, slot use 1/15)
Bulk: tx_pending=0 (size 0), rx_pending=0 (size 0)
Ctrl: tx_count=16, tx_bytes=100, rx_count=16, rx_bytes=16
Bulk: tx_count=0, tx_bytes=0, rx_count=0, rx_bytes=0
0 quota stalls, 0 slot stalls, 0 bulk stalls, 0 aborted, 0 errors
instance dadbc800, 0/64 messages (dequeue pending)
Service 1: LISTENING (ref 1) 'KEEP' remote n/a (msg use 0/3840, slot use 0/15)
Bulk: tx_pending=0 (size 0), rx_pending=0 (size 0)
Ctrl: tx_count=0, tx_bytes=0, rx_count=0, rx_bytes=0
Bulk: tx_count=0, tx_bytes=0, rx_count=0, rx_bytes=0
0 quota stalls, 0 slot stalls, 0 bulk stalls, 0 aborted, 0 errors
instance dacaf920
I was quite easy to move the power driver, so I'll do that. drivers/power was the wrong place, so I moved it to drivers/soc/bcm2835. So I'll make a PR for that, then I'll do one for vc-mem.
@pelwell With those in place it's possible to boot ARC_BCM2835 directly from VC and with vc-mem in place, I think it's better that you continue with tracking down where/why this fails at your leisure.
Thanks, that's appreciated. It's on my list.
ARCH_BCM2835 is not able to halt, it just reboots. This change fixes that:
+static int calc_rsts(int partition)
+{
+ return PM_PASSWORD |
+ ((partition & (1 << 0)) << 0) |
+ ((partition & (1 << 1)) << 1) |
+ ((partition & (1 << 2)) << 2) |
+ ((partition & (1 << 3)) << 3) |
+ ((partition & (1 << 4)) << 4) |
+ ((partition & (1 << 5)) << 5);
+}
+
/*
* We can't really power off, but if we do the normal reset scheme, and
* indicate to bootcode.bin not to reboot, then most of the chip will be
* powered off.
*/
static void bcm2835_power_off(void)
{
u32 val;
/*
* We set the watchdog hard reset bit here to distinguish this reset
* from the normal (full) reset. bootcode.bin will not reboot after a
* hard reset.
*/
val = readl_relaxed(wdt_regs + PM_RSTS);
val &= ~PM_RSTC_WRCFG_MASK;
val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
+
+ /* partition 63 is special code for HALT the bootloader knows not to boot*/
+ val = calc_rsts(63);
+
writel_relaxed(val, wdt_regs + PM_RSTS);
/* Continue with normal reset mechanism */
bcm2835_restart(REBOOT_HARD, "");
}
What's the reasoning behind the calc_rsts() formula?
bcm2835_power_off() reads PM_RSTS and uses part of that value when writing back, but arch/arm/mach-bcm2708/bcm2708.c only writes. Care to elaboarate on this?
There are 6 bits of "state" that are preserved over a reset in the PM_RSTS register. We use them for signalling information to bootcode.bin over a reset.
NOOBS writes a partition number before rebooting to support multiboot. 63 is treated as a magic number to indicate we don't want to reboot (i.e. we are halting).
calc_rsts is historical. Looks like (PM_PASSWORD | (partition & 0x3f)) would be equivalent. I suspect that earlier we only allocated a few of the bits, so it did a non-linear mapping of bits.
Looks like (PM_PASSWORD | (partition ^ 0x3f)) would be equivalent.
That would not give the same value:
63 == 0x3f == 0b11111
calc_rsts(63) & 0xffff = 0x555 == 010101010101 (every other bit is used)
63 ^ 0x3f = 0
Is get_rsts being masked somehow, because I don't get the 0x555 value back:
Power on
$ vcgencmd get_rsts
get_rsts=1000 == 0001 0000 0000 0000 == BIT(12)
Reboot
$ vcgencmd get_rsts
get_rsts=1020 == 0001 0000 0010 0000 == BIT(12) | BIT(5)
PM_RSTS flags
12 HADPOR Had a power-on reset
5 HADWRF Had a watchdog full reset
The ^ was corrected to an & just after I posted it yesterday.
This did not work, it rebooted instead of halting:
val = PM_PASSWORD | (63 & 0x3f);
$ vcgencmd get_rsts
get_rsts=37
I expected to get 0x3f here, but bit 3 is zero: PM_RSTS 3 - Unused R
Sorry I misread calc_rsts. The six-bit partition is spread into bits 0, 2, 4, 6, 8, 10 of RSTS.
I don't believe we want to preserve anything in there so I'd say:
static void bcm2835_power_off(void)
{
/* partition 63 is special code for HALT the bootloader knows not to boot*/
u32 val = calc_rsts(63);
writel_relaxed(val, wdt_regs + PM_RSTS);
/* Continue with normal reset mechanism */
bcm2835_restart(REBOOT_HARD, "");
}
looks right.
These arch/arm/mach-bcm270x/bcm270x.c devices have not been moved to Device Tree.
uart0
AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
static struct amba_device *amba_devs[] __initdata = {
&uart0_device,
};
amba_device_register(d, &iomem_resource);
See #910
bcm2708_systemtimer
bcm_register_device(&bcm2708_systemtimer_device);
This device does not have a matching driver. It's intended role seems to have been fulfilled by bcm2708_clocksource_init(). On BCM2709 it is disabled because SYSTEM_TIMER is not defined.
serial8250
bcm_register_device(&bcm2708_uart1_device);
The driver for this device is not enabled (SERIAL_8250). Only the Compute Module has access to the necessary pins if I'm not mistaken.
To simplify the life for those wanting to use this, I suggest adding a DT node. I have tried to construct one based on bcm2708_uart1_platform_data. This is not tested.
uart1: uart@7e215040 {
compatible = "ns16550";
reg = <0x7e215040 0x40>;
interrupts = <1 29>;
clock-frequency = <500000000>; // a regular clocks property can also be used
reg-shift = <2>;
no-loopback-test;
status = "disabled";
};
kconfig: SERIAL_8250 SERIAL_OF_PLATFORM
Links: https://www.kernel.org/doc/Documentation/devicetree/bindings/serial/8250.txt http://lxr.free-electrons.com/source/drivers/tty/serial/of_serial.c http://lxr.free-electrons.com/source/drivers/tty/serial/8250/
bcm2708_powerman
bcm_register_device(&bcm2708_powerman_device);
This device does not have a matching driver. It was probably meant to be used with the bcm2708-power module.
bcm2835_hwmon
bcm_register_device(&bcm2835_hwmon_device);
The matching bcm2835_hwmon driver is not enabled (can't be used alongside bcm2835-thermal):
The 8250/pl011 UART (uart1) can use the same pins as the mini UART (uart0), but not at the same time. If you configure GPIOs 14-15 (and 16-17 if you want RTS/CTS) to ALT5 then you will lose ttyAMA0, but gain a way to use UART1.
This is a list of the devices in arch/arm/mach-bcm2709/bcm2709.c that isn't loaded through Device Tree:
This driver allocates DMA channels. The bcm2835-dma driver will take care of this on ARCH_BCM2835.
Mailbox driver. Eric Anholt has worked on upstreaming this functionality, not sure of the current status.
I could not find the driver that uses this.
This device can move to DT (driver depends on mailbox and dma). Probably still a while until the vc4 graphics driver is ready.
Device can move to DT. This usb driver will probably stay with us for some time.
This device should be possible to move to DT, but I don't have a CM to test with.
I could not find the driver that uses this. Maybe arch/arm/mach-bcm2708/power.c was meant to use it?
Devices can move to DT.
The device can move to DT (driver depends on mailbox). Driver is not enabled in the default config.
The device can move to DT (driver depends on mailbox).
PR #910 (BCM270x_DT: Configure UART using DT)
I have made a patch for the following devices: bcm2708_fb_device, bcm2708_usb_device, bcm2708_alsa_devices[0-7], bcm2835_thermal_device Patch: https://gist.github.com/notro/882b88430626269d0572 (the patch is for Pi2 against rpi-4.0.y)
Audio: Should we use 2708 in the compatibility string to avoid a possible clash with a future mainline driver?
Are these in use: bcm2708_systemtimer_device, bcm2708_powerman_device ?
I can make a PR if this is useful. Comments are welcome.