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

ARCH_BCM270x: Moving more devices to DT #936

Closed
notro opened this issue Apr 20, 2015 · 107 comments
Closed

ARCH_BCM270x: Moving more devices to DT #936

notro opened this issue Apr 20, 2015 · 107 comments

Comments

@notro
Copy link
Contributor

notro commented Apr 20, 2015

This is a list of the devices in arch/arm/mach-bcm2709/bcm2709.c that isn't loaded through Device Tree:

  • bcm2708_dmaman_device
    This driver allocates DMA channels. The bcm2835-dma driver will take care of this on ARCH_BCM2835.
  • bcm2708_vcio_device
    Mailbox driver. Eric Anholt has worked on upstreaming this functionality, not sure of the current status.
  • bcm2708_systemtimer_device
    I could not find the driver that uses this.
  • bcm2708_fb_device
    This device can move to DT (driver depends on mailbox and dma). Probably still a while until the vc4 graphics driver is ready.
  • bcm2708_usb_device
    Device can move to DT. This usb driver will probably stay with us for some time.
  • bcm2708_uart1_device
    This device should be possible to move to DT, but I don't have a CM to test with.
  • bcm2708_powerman_device
    I could not find the driver that uses this. Maybe arch/arm/mach-bcm2708/power.c was meant to use it?
  • bcm2708_alsa_devices[0-7]
    Devices can move to DT.
  • bcm2835_hwmon_device
    The device can move to DT (driver depends on mailbox). Driver is not enabled in the default config.
  • bcm2835_thermal_device
    The device can move to DT (driver depends on mailbox).
  • amba_devs (uart0)
    PR BCM270x_DT: Configure UART using DT #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?

    audio@0 {
        compatible = "bcrm,bcm2835-audio";
        compatible = "bcrm,bcm2708-audio";
    };

Are these in use: bcm2708_systemtimer_device, bcm2708_powerman_device ?

I can make a PR if this is useful. Comments are welcome.

@notro
Copy link
Contributor Author

notro commented Apr 21, 2015

I now have the dwc_otg driver working (no fiq) with ARCH_BCM2835, well partly #937
It will be interesting to see how many of the other drivers I can get working.

@popcornmix
Copy link
Collaborator

Sounds good to me.

@notro
Copy link
Contributor Author

notro commented Apr 21, 2015

How do you want it:

  1. One commit per driver and one commit for all the devices
  2. One commit per driver and one commit per device

@popcornmix
Copy link
Collaborator

Not too bothered. I'll say one commit per device as it's easier to squash than split.

@notro
Copy link
Contributor Author

notro commented Apr 25, 2015

AFAICT I now have the major 2708 drivers (mostly) working on ARCH_BCM2835!
This was really fun to pull through. I have tried a couple of times over the last year to do this, but each time dwc_otg would hang on reset and I gave up.
I haven't done much testing, but all drivers have signs of "life".

dwc_otg

No FIQ support which leads to broken low speed device support.
Network OK:

$ ping -c 1 raspberrypi.org
PING raspberrypi.org (149.126.74.185) 56(84) bytes of data.
64 bytes from 149.126.74.185.ip.incapdns.net (149.126.74.185): icmp_req=1 ttl=51 time=33.5 ms

--- raspberrypi.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 33.592/33.592/33.592/0.000 ms

When trying to boot directly from VC without u-boot, it breaks:

[    1.827405] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)
[    2.033412] Core Release: 2.80a
[    2.036697] Setting default values for core params
[    2.041570] Finished setting default values for core params
[    2.060618] WARN::dwc_otg_core_reset:5109: dwc_otg_core_reset() HANG! Soft Reset GRSTCTL=80000001
[    2.060618]
[    2.183995] WARN::dwc_otg_core_reset:5109: dwc_otg_core_reset() HANG! Soft Reset GRSTCTL=80000001
[    2.183995]

bcm2708_dma

Copied to drivers/dma/bcm2708-dma.c

bcm2835-mmc

$ sync; time dd if=/dev/zero of=~/test.tmp bs=500K count=1024
1024+0 records in
1024+0 records out
524288000 bytes (524 MB) copied, 36.123 s, 14.5 MB/s

real    0m36.143s
user    0m0.020s
sys     0m15.160s

bcm2708_vcio

Copied to drivers/mailbox/bcm2708-vcio.c

bcm2835-thermal

$ cat /sys/class/thermal/thermal_zone0/temp
35780

bcm2708_fb

HDMI is ok. Not sure if the DMA part is tested by just starting X windows.
Based on work by Lubomir Rintel.

vchiq

$ vcgencmd measure_temp
temp=35.8'C

Based on work by Lubomir Rintel.

bcm2835_AUD0

omxplayer crashed the kernel (8 blinks on the green led).
aplay gives me mono sound:

$ aplay /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono

vc_mem

Copied to drivers/char/broadcom/vc_mem.c

$ sudo vcdbg log msg 2>&1 | grep Loading
000913.584: Loading 'kernel.img' from SD card

Here's the diff: https://gist.github.com/notro/dbb63a021d8ea575ddb5
Kernel boot messages: https://gist.github.com/notro/142ac6e5caf1631cc639

@popcornmix are you interested in pulling something like this?

@popcornmix
Copy link
Collaborator

Sounds awesome! Yes, this is something I'm very interested in.
Pi1 only for now I guess? What are you using as the .config? bcm2835_defconfig?

[ 0.272560] DMA: preallocated 256 KiB pool for atomic coherent allocations
looks a bit low for vchiq (and possible dwc).

Any thoughts on why uboot is required? Is uboot doing some reset/init/power/clock setup of dwc that is not occurring with 2835 arch? Would be good to get this solved.
If the FIQ not working another init step missing, or not supported in interrupt driver?

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

Pi1 only for now I guess?

Yes.
I see that Eric Anholt is working on getting Pi2 support into mainline, so when that happens, I guess this should work on the Pi2 as well.

I don't know why this is address bit must be set though, it might be different on the Pi2:
bcm2708_fb

#ifdef CONFIG_ARCH_BCM2835
#define TO_VC_PHYS(a)   (0x40000000 | (a))
    bcm_mailbox_write(MBOX_CHAN_FB, TO_VC_PHYS(fb->dma));
#else
    bcm_mailbox_write(MBOX_CHAN_FB, fb->dma);
#endif

What are you using as the .config? bcm2835_defconfig?

Yes.
Should we make changes to it or should we make a new config for this work?
I'm planning to add all the modules from bcmrpi_defconfig when I'm done with these drivers.

[ 0.272560] DMA: preallocated 256 KiB pool for atomic coherent allocations
looks a bit low for vchiq (and possible dwc).

Yes, I got an allocation failure in vchiq at first:

    g_slot_mem = dma_alloc_coherent(NULL, g_slot_mem_size + frag_mem_size,
        &g_slot_phys, GFP_ATOMIC);

I couldn't see why this needed to be atomic (during init/probe), so I changed it to GFP_KERNEL. It worked fine after that.
Is 256 KiB too small for dwc_otg?

Any thoughts on why uboot is required? Is uboot doing some reset/init/power/clock setup of dwc that is not occurring with 2835 arch? Would be good to get this solved.

I didn't do arch/arm/mach-bcm2708/power.c, because of this statement: This driver provides a mailbox interface to power up/down the domains that notionally belong to the ARM, however currently this is not used by any of the peripheral drivers.
But looking at it, I see:

#ifdef CONFIG_USB
#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB)
#endif

static int __init bcm_power_init(void)
{
[...]
#if defined(BCM_POWER_ALWAYS_ON)
    if (BCM_POWER_ALWAYS_ON) {
        bcm_power_open(&always_on_handle);
        bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON);
    }
#endif

So USB power seems to be the missing piece. I'll try it.

If the FIQ not working another init step missing, or not supported in interrupt driver?

Not supported in the irq driver. @P33M made this comment:

Regarding FIQ support - the mach-bcm2835 armctrl IRQchip needs expanding to write to the FIQ select register. FIQ lines in ARM linux are just IRQ numbers >= FIQ_START. Some sort of refcounting would be required to ensure that the FIQ is not enabled from different sources simultaneously - the hardware can only support a single, nominated IRQ line to promote to the FIQ input.

@popcornmix
Copy link
Collaborator

#ifdef CONFIG_ARCH_BCM2835
#define TO_VC_PHYS(a)   (0x40000000 | (a))
    bcm_mailbox_write(MBOX_CHAN_FB, TO_VC_PHYS(fb->dma));
#else
    bcm_mailbox_write(MBOX_CHAN_FB, fb->dma);
#endif

Looks wrong for 2836. I suspect this offset should be:
https://github.com/raspberrypi/linux/blob/rpi-3.18.y/arch/arm/mach-bcm2709/include/mach/memory.h#L39

so wants to be 0xC0000000 (bypassing the GPU caches) on 2836.

I think modifying the upstream bcm2835_defconfig is okay. We are modifying other upstream files, so trying to build an clean upstream kernel from this tree is not advisable.

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

bypassing the GPU caches

Then why is this not needed on ARCH_BCM2708?

Isn't there some dma sync function that we can use instead of bypassing the cache?

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

Is USB the only peripheral that the firmware doesn't power on?
If so, why can't it turn on that as well?

@popcornmix
Copy link
Collaborator

Read this message for details on the different cache aliases:
http://lists.denx.de/pipermail/u-boot/2015-March/208201.html

The bcm2708_fb driver on Pi2 reports:
[ 1.552500] BCM2708FB: allocated DMA memory e7c00000

and on Pi1 reports:
[ 1.377893] BCM2708FB: allocated DMA memory 4fc00000

so it is allocing a bus address suitable for use by GPU. We convert this back into an ARM physical address here: https://github.com/raspberrypi/linux/blob/rpi-3.18.y/drivers/video/fbdev/bcm2708_fb.c#L316

@popcornmix
Copy link
Collaborator

Originally I believe MMC and USB required powering from the arm side. I think the linux driver powered "on demand" which slowed down the MMC driver and meant if the GPU locked up you lost access to MMC which was unfortunate, so that got removed.

Removing power control of USB and making it always on and powered by the GPU may make sense. It rules out a (very small) power saving possible from the arm side, but we're not taking advantage of that. @pelwell @P33M any objection to enabling USB power from GPU by default?

@P33M
Copy link
Contributor

P33M commented Apr 26, 2015

I agree that the use case where we would want USB turned off is of marginal benefit - the power consumption versus connectivity tradeoff doesn't really make sense.

As it removes some complexity (for now) from the ARM side code then it seems reasonable to just change the default state in firmware, but in the future we would want the state to be communicated to whatever PM/power domain driver that exists in the upstream world.

@pelwell
Copy link
Contributor

pelwell commented Apr 26, 2015

No objection from me.

@popcornmix
Copy link
Collaborator

@notro can you post you config? I suspect you are not using an untouched bcm2835_defconfig as that doesn't have CONFIG_MAILBOX enabled.

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

Sorry I forgot that, I set the config in a script.
Here's the diff: https://gist.github.com/notro/5db4d2c30996c1b58270
I don't know why some of the options are removed though, the only one I actively disabled was FB_SIMPLE.

@popcornmix
Copy link
Collaborator

@notro I just get
Uncompressing Linux... done, booting the kernel.
and nothing else. I'm just trying to get the direct (no uboot) case to work. Do you have any config.txt/cmdline.txt settings? Did you run mkknlimg --dtok on the kernel?

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

There is something wrong with that diff I gave, because some of the options are not disable in the kernel:

pi@raspberrypi:~$ zgrep "CONFIG_RD_" /proc/config.gz
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y

I'll have to look into this.

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

These are the options I set/change in my script:

  VAR['LINUX_DEFCONFIG'] = 'bcm2835_defconfig'

  config 'DYNAMIC_DEBUG', :enable
  config ['CONFIG_IKCONFIG', 'CONFIG_IKCONFIG_PROC'], :enable
  config 'PROC_DEVICETREE', :enable

  config ['DMADEVICES', 'DMA_BCM2708'], :enable
  config 'MMC_BCM2835', :enable
  config 'MMC_BCM2835_DMA', :enable

  config 'USB_DWCOTG', :enable

  config 'THERMAL', :enable
  config 'THERMAL_BCM2835', :enable

  config 'MAILBOX', :enable
  config 'BCM2708_MBOX', :enable


  config 'FB_BCM2708', :enable
  config 'FB_SIMPLE', :disable

  config 'SOUND', :enable
  config 'SND', :enable #:module
  config 'SND_BCM2835', :enable #:module

  config 'BRCM_CHAR_DRIVERS', :enable
  config 'BCM2708_VCMEM_2', :enable

@popcornmix
Copy link
Collaborator

Can you run
make ARCH=arm savedefconfig
and post the defconfig file?

Do you have any config.txt/cmdline.txt settings? Did you run mkknlimg --dtok on the kernel?

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

Am I doing something wrong here:

$ grep "CONFIG_RD_" arch/arm/configs/bcm2835_defconfig
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y

$ grep "CONFIG_RD_" .config
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y

$ ARCH=arm make savedefconfig
$ grep "CONFIG_RD_" defconfig
$ #nothing

defconfig: https://gist.github.com/notro/62767303672ebba49161
.config: https://gist.github.com/notro/5fabf78966d91eeec205

Do you have any config.txt/cmdline.txt settings?

No

Did you run mkknlimg --dtok on the kernel?

Yes when I tested booting directly without uboot.

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

Do you have any config.txt/cmdline.txt settings?

Sorry, /boot/config.txt: device_tree=bcm2835-rpi-b-plus.dtb

@popcornmix
Copy link
Collaborator

Am I doing something wrong here:

The defconfigs only list non-default options, so it's expected to have more options in .config than in the original defconfig. Now if a newly created defconfig has even fewer options, then that suggests the original defconfig had some invalid (or already default) options in that have been removed.

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

How do we treat the arch modules: dma.c, vc_mem.c, vcio.c?
vc_mem can be just moved as is without any changes. It gets it's config from the kernel command line.
The other two, should we move them or make a copy just for ARCH_BCM2835?
vcio.c for instance hardcodes mem and irq, so if we move it that would have to be taken care of for 270x.
dma.c hardcodes it's irqs so that would also need to be fixed for 270x.

If we don't move, the depending drivers would need different includes for ARCH_BCM2835.

What we choose depends on how long until we reach ARCH_BCM2835, and the expected future changes to these drivers. If we have copies, both would need updating.
From a purist point of view having 2 almost identical drivers is an abomination, but we are quite pragmatic in this remote part of the kernel world :-) And it is a transitional phase.

So what do you think?

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

It doesn't sound right to make copies of the drivers... sigh.
Maybe I just have to take the time to do it "right". It's the testing that takes so much time, 2 kernels x 2 modes + 2835 kernel. While taking care not to break anything in between these commits...

dma PR with 7 commits:

  • copy dma.c to drivers/dma/bcm2708-dma.c and make irq changes, add DT support.
  • Add irqs to device in bcm270x.c and add node to DT
  • disable dma.c and enable drivers/dma/bcm2708-dma.c.
    arch/arm/mach-bcm2708/include/mach/dma.h will just include include/linux/dma/dma-bcm2708.h
  • delete arch/arm/mach-bcm270x/dma.c
  • fix bcm2708-dmaengine to continue using legacy DMA driver on ARCH_BCM2835
  • ARCH_BCM2835 add DT nodes
  • bcm2835_defconfig enable DMA

@pelwell
Copy link
Contributor

pelwell commented Apr 26, 2015

I think we need to move to using platform devices to configure the existing hardcoded drivers. We should also - either at the same time or later - remove the 2708/2709 duplication.

@notro
Copy link
Contributor Author

notro commented Apr 26, 2015

Yes, perhaps I should first make a PR that fixes the hardcoding and then do one for ARCH_BCM2835. That will make it easier on me :-)

BCM270x: Add irq resources to dmaman device
BCM270x: dma: Use irq resources instead of hardcoded values
BCM270x: dma: Add Device Tree support
BCM270x: Add dma Device Tree node and use it

dma: Add bcm2708 legacy driver (plain copy of dma.c)
BCM270x: Use drivers/dma/bcm2708-dma.c
BCM270x: dma: Remove driver
bcm2835: Add legacy DMA DT node
bcm2835: Enable DMA in defconfig

Another solution is to merge dma.c with bcm2708-dmaengine.c:

BCM270x: Add memory and irq resources to dmaengine device and DT
dmaengine: bcm2708: Merge with arch dma.c driver and disable dma.c
BCM270x: Remove dmaman device
BCM270x: dma: Remove driver

dmaengine: bcm2708: Add depends on ARCH_BCM2835
bcm2835: Enable DMA_BCM2708 in defconfig

That will give us just one device/driver for the DMA controller.
Maybe this one is better?

@notro
Copy link
Contributor Author

notro commented Apr 27, 2015

Patch merging dma.c with bcm2708-dmaengine.c: https://gist.github.com/notro/656e0c483089a0bf4138
Please have a look and tell me what you think.

Changes to the dma.c code during merging:
Fix a couple of whitespace issues.
Cutdown some comments to one line.
Add mutex to vc_dmaman and use this, since the dev lock is locked during probing of the engine part.
Add global g_dmaman variable since drvdata is used by the engine part.
Restructure bcm_dma_chan_alloc() to simplify error handling.
Use device irq resources instead of hardcoded bcm_dma_irqs table.
Remove dev_dmaman_register() and code it directly.
dev_dmaman_deregister() and code it directly.
Get dmachans from DT if available.
Use dev_* instead of printk.
Keep 'dma.dmachans' module property name for backwards compatibility.

I'm uncertain about dmachans. The firmware only sets the module parameter and not the DT property.
Should I skip DT support, or should we add support in firmware?

@popcornmix
Copy link
Collaborator

I guess firmware should set dmachans in DT. @pelwell?

@pelwell
Copy link
Contributor

pelwell commented Apr 28, 2015

Let's leave this in as a default to aid the transition, then I'll patch it from the firmware.

@notro
Copy link
Contributor Author

notro commented May 21, 2015

@notro
Copy link
Contributor Author

notro commented May 21, 2015

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?

@pelwell
Copy link
Contributor

pelwell commented May 21, 2015

Put it in bcm2708_common.dtsi - it is a feature common to BCM2835 and BCM2836, even if it isn't used.

@pelwell
Copy link
Contributor

pelwell commented May 21, 2015

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"

@notro
Copy link
Contributor Author

notro commented May 21, 2015

@pelwell
Copy link
Contributor

pelwell commented May 21, 2015

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.

@notro
Copy link
Contributor Author

notro commented May 21, 2015

$ 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:

  • Turn on in firmware.
  • Move arch/arm/mach-bcm2708/power.c to drivers/power/bcm2708-power.c and keep it as-is (not turn it into a driver).

@pelwell
Copy link
Contributor

pelwell commented May 21, 2015

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?

@notro
Copy link
Contributor Author

notro commented May 21, 2015

$ 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

@notro
Copy link
Contributor Author

notro commented May 21, 2015

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.

@pelwell
Copy link
Contributor

pelwell commented May 21, 2015

Thanks, that's appreciated. It's on my list.

@notro
Copy link
Contributor Author

notro commented May 22, 2015

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?

@popcornmix
Copy link
Collaborator

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.

@notro
Copy link
Contributor Author

notro commented May 23, 2015

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

Ref: #932

@popcornmix
Copy link
Collaborator

The ^ was corrected to an & just after I posted it yesterday.

@notro
Copy link
Contributor Author

notro commented May 23, 2015

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

@popcornmix
Copy link
Collaborator

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.

@notro
Copy link
Contributor Author

notro commented Jun 2, 2015

BCM270x Device Tree status

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):

@pelwell
Copy link
Contributor

pelwell commented Jun 2, 2015

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.

@popcornmix
Copy link
Collaborator

I suspect bcm2835_hwmon can be dropped. I don't think it gives us anything over bcm2835-thermal (unless anyone knows better).

@notro
Copy link
Contributor Author

notro commented Jun 4, 2015

I suspect bcm2835_hwmon can be dropped.

Apparently the thermal driver can act as a hwmon device in case someone should need that:

config THERMAL_HWMON
        bool
        prompt "Expose thermal sensors as hwmon device"
        depends on HWMON=y || HWMON=THERMAL
        default y
        help
          In case a sensor is registered with the thermal
          framework, this option will also register it
          as a hwmon. The sensor will then have the common
          hwmon sysfs interface.

          Say 'Y' here if you want all thermal sensors to
          have hwmon sysfs interface too.

http://lxr.free-electrons.com/source/drivers/thermal/Kconfig

@notro
Copy link
Contributor Author

notro commented Jun 6, 2015

Here's a proposal for uart1:

diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi
+       uart1: uart@7e215040 {
+           compatible = "brcm,bcm2835-aux-uart", "ns16550";
+           reg = <0x7e215040 0x40>;
+           interrupts = <1 29>;
+           clock-frequency = <500000000>;
+           reg-shift = <2>;
+           no-loopback-test;
+           status = "disabled";
+       };
+

diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+   /* Turn on the mini uart if it is used */
+   np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart");
+   if (of_device_is_available(np)) {
+       pr_info("%s: Turn on Mini UART\n", __func__);
+       writel(1, __io_address(UART1_BASE + 0x4));
+   } else {
+       bcm_register_device_dt(&bcm2708_uart1_device);
+   }
+

uart1 will only be used on the Compute Module and it won't work without a patch that enables it in AUXENB.
So maybe we should just remove bcm2708_uart1_device since it currently doesn't work?
Or should we make it work without DT also: https://www.raspberrypi.org/forums/viewtopic.php?p=769921#p769921

@pelwell
Copy link
Contributor

pelwell commented Jun 6, 2015

Making it work without DT sends the wrong message. James has just written a good tutorial on CM + DT, so I can't think of a good reason not to use DT.

@notro
Copy link
Contributor Author

notro commented Jun 6, 2015

Glad to hear that, I'll make a PR.

@notro
Copy link
Contributor Author

notro commented Jun 7, 2015

All devices have a Device Tree counterpart now and ARCH_BCM2835 is working with all drivers (except dwc_otg and lirc_rpi), so mission accomplished.

@notro notro closed this as completed Jun 7, 2015
@popcornmix
Copy link
Collaborator

Thanks @notro!

popcornmix pushed a commit that referenced this issue Aug 22, 2024
Booting with CONFIG_DEBUG_VIRTUAL leads to following warning when
passing hugepage reservation on command line:

  Kernel command line: hugepagesz=1g hugepages=1 hugepagesz=64m hugepages=1 hugepagesz=256m hugepages=1 noreboot
  HugeTLB: allocating 1 of page size 1.00 GiB failed.  Only allocated 0 hugepages.
  ------------[ cut here ]------------
  WARNING: CPU: 0 PID: 0 at arch/powerpc/include/asm/io.h:948 __alloc_bootmem_huge_page+0xd4/0x284
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper Not tainted 6.10.0-rc6-00396-g6b0e82791bd0-dirty #936
  Hardware name: MPC8544DS e500v2 0x80210030 MPC8544 DS
  NIP:  c1020240 LR: c10201d0 CTR: 00000000
  REGS: c13fdd30 TRAP: 0700   Not tainted  (6.10.0-rc6-00396-g6b0e82791bd0-dirty)
  MSR:  00021000 <CE,ME>  CR: 44084288  XER: 20000000

  GPR00: c10201d0 c13fde20 c130b560 e8000000 e8001000 00000000 00000000 c1420000
  GPR08: 00000000 00028001 00000000 00000004 44084282 01066ac0 c0eb7c9c efffe149
  GPR16: c0fc4228 0000005f ffffffff c0eb7d0c c0eb7cc0 c0eb7ce0 ffffffff 00000000
  GPR24: c1441cec efffe153 e8001000 c14240c0 00000000 c1441d64 00000000 e8000000
  NIP [c1020240] __alloc_bootmem_huge_page+0xd4/0x284
  LR [c10201d0] __alloc_bootmem_huge_page+0x64/0x284
  Call Trace:
  [c13fde20] [c10201d0] __alloc_bootmem_huge_page+0x64/0x284 (unreliable)
  [c13fde50] [c10207b8] hugetlb_hstate_alloc_pages+0x8c/0x3e8
  [c13fdeb0] [c1021384] hugepages_setup+0x240/0x2cc
  [c13fdef0] [c1000574] unknown_bootoption+0xfc/0x280
  [c13fdf30] [c0078904] parse_args+0x200/0x4c4
  [c13fdfa0] [c1000d9c] start_kernel+0x238/0x7d0
  [c13fdff0] [c0000434] set_ivor+0x12c/0x168
  Code: 554aa33e 7c042840 3ce0c142 80a7427c 5109a016 50caa016 7c9a2378 7fdcf378 4180000c 7c052040 41810160 7c095040 <0fe00000> 38c00000 40800108 3c60c0eb
  ---[ end trace 0000000000000000 ]---

This is due to virt_addr_valid() using high_memory before it is set.

high_memory is set in mem_init() using max_low_pfn, but max_low_pfn
is available long before, it is set in mem_topology_setup(). So just
like commit daa9ada ("powerpc/mm: Fix boot crash with FLATMEM")
moved the setting of max_mapnr immediately after the call to
mem_topology_setup(), the same can be done for high_memory.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/62b69c4baad067093f39e7e60df0fe27a86b8d2a.1723100702.git.christophe.leroy@csgroup.eu
ncopa pushed a commit to ncopa/linux that referenced this issue Sep 19, 2024
[ Upstream commit e7e846d ]

Booting with CONFIG_DEBUG_VIRTUAL leads to following warning when
passing hugepage reservation on command line:

  Kernel command line: hugepagesz=1g hugepages=1 hugepagesz=64m hugepages=1 hugepagesz=256m hugepages=1 noreboot
  HugeTLB: allocating 1 of page size 1.00 GiB failed.  Only allocated 0 hugepages.
  ------------[ cut here ]------------
  WARNING: CPU: 0 PID: 0 at arch/powerpc/include/asm/io.h:948 __alloc_bootmem_huge_page+0xd4/0x284
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper Not tainted 6.10.0-rc6-00396-g6b0e82791bd0-dirty raspberrypi#936
  Hardware name: MPC8544DS e500v2 0x80210030 MPC8544 DS
  NIP:  c1020240 LR: c10201d0 CTR: 00000000
  REGS: c13fdd30 TRAP: 0700   Not tainted  (6.10.0-rc6-00396-g6b0e82791bd0-dirty)
  MSR:  00021000 <CE,ME>  CR: 44084288  XER: 20000000

  GPR00: c10201d0 c13fde20 c130b560 e8000000 e8001000 00000000 00000000 c1420000
  GPR08: 00000000 00028001 00000000 00000004 44084282 01066ac0 c0eb7c9c efffe149
  GPR16: c0fc4228 0000005f ffffffff c0eb7d0c c0eb7cc0 c0eb7ce0 ffffffff 00000000
  GPR24: c1441cec efffe153 e8001000 c14240c0 00000000 c1441d64 00000000 e8000000
  NIP [c1020240] __alloc_bootmem_huge_page+0xd4/0x284
  LR [c10201d0] __alloc_bootmem_huge_page+0x64/0x284
  Call Trace:
  [c13fde20] [c10201d0] __alloc_bootmem_huge_page+0x64/0x284 (unreliable)
  [c13fde50] [c10207b8] hugetlb_hstate_alloc_pages+0x8c/0x3e8
  [c13fdeb0] [c1021384] hugepages_setup+0x240/0x2cc
  [c13fdef0] [c1000574] unknown_bootoption+0xfc/0x280
  [c13fdf30] [c0078904] parse_args+0x200/0x4c4
  [c13fdfa0] [c1000d9c] start_kernel+0x238/0x7d0
  [c13fdff0] [c0000434] set_ivor+0x12c/0x168
  Code: 554aa33e 7c042840 3ce0c142 80a7427c 5109a016 50caa016 7c9a2378 7fdcf378 4180000c 7c052040 41810160 7c095040 <0fe00000> 38c00000 40800108 3c60c0eb
  ---[ end trace 0000000000000000 ]---

This is due to virt_addr_valid() using high_memory before it is set.

high_memory is set in mem_init() using max_low_pfn, but max_low_pfn
is available long before, it is set in mem_topology_setup(). So just
like commit daa9ada ("powerpc/mm: Fix boot crash with FLATMEM")
moved the setting of max_mapnr immediately after the call to
mem_topology_setup(), the same can be done for high_memory.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/62b69c4baad067093f39e7e60df0fe27a86b8d2a.1723100702.git.christophe.leroy@csgroup.eu
Signed-off-by: Sasha Levin <sashal@kernel.org>
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

No branches or pull requests

4 participants