Comment 20 for bug 1691991

Revision history for this message
Daniel Axtens (daxtens) wrote :

Hi,

On further investigation it turns out that one large difference between my x86 system and the arm64 system is they way the vga arbiter is operating in the kernel. This means that the vga card isn't labelled as the "boot vga" card, which affects how it's picked up by X.

On the HiSilicon board, I'm seeing:

[ 0.815343] pci 0007:a1:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
[ 0.815355] pci 0007:a1:00.0: vgaarb: bridge control possible
[ 0.815360] vgaarb: loaded

On an x86 vm I'm seeing:

[ 0.390696] vgaarb: setting as boot device: PCI:0000:00:02.0
[ 0.391245] vgaarb: device added: PCI:0000:00:02.0,decodes=io+mem,owns=io+mem,locks=none
[ 0.393421] vgaarb: loaded
[ 0.393811] vgaarb: bridge control possible 0000:00:02.0

(The difference in the format is due to different kernel versions)

Looking at the kernel source, it looks like the owns= section is getting blanked because of the bridge that the VGA card is sitting behind.

From drivers/gpu/vga/vgaarb.c:

        /* Mark that we "own" resources based on our enables, we will
         * clear that below if the bridge isn't forwarding
         */
        pci_read_config_word(pdev, PCI_COMMAND, &cmd);
        if (cmd & PCI_COMMAND_IO)
                vgadev->owns |= VGA_RSRC_LEGACY_IO;
        if (cmd & PCI_COMMAND_MEMORY)
                vgadev->owns |= VGA_RSRC_LEGACY_MEM;

        /* Check if VGA cycles can get down to us */
        bus = pdev->bus;
        while (bus) {
                bridge = bus->self;
                if (bridge) {
                        u16 l;

                        pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &l);
                        if (!(l & PCI_BRIDGE_CTL_VGA)) {
                                vgadev->owns = 0;
                                break;
                        }
                }
                bus = bus->parent;
        }

        /* Deal with VGA default device. Use first enabled one
         * by default if arch doesn't have it's own hook
         */
        if (vga_default == NULL &&
            ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
                vgaarb_info(&pdev->dev, "setting as boot VGA device\n");
                vga_set_default_device(pdev);

Perhaps X should be be picking up the card through PCI probing on arm64 rather than platform probing which seems to rely a bit on boot VGA devices. I will check this. But first I just wanted to check the PCI topology: is the card behind any unusual bridges or switches?

I can write some kernel code next week to find out specifically why this isn't being picked up, but I thought I'd check for HW quirks first.