----- Original Message ---- From: Marc Jones marc.jones@amd.com To: Jonathan Sturges jonathansturges@yahoo.com Cc: LinuxBIOS mailing list linuxbios@linuxbios.org Sent: Tuesday, September 25, 2007 12:05:19 PM Subject: Re: [LinuxBIOS] Two more CS5530 IRQ steering questions
Jonathan Sturges wrote:
Jonathan Sturges wrote: Two additional questions about CS5530 IRQ steering:
Comments from Uwe Hermann and Peter Stuge have indicated that it's really better for the kernel to setup the steering registers. Why is this? It sounds like the BIOS is a good place to set these. I assume that a knowledgeable OS could change them if necessary? At the very least, it does sound like we all agree that it's OK to have LB setup the steering until Linux is fixed.
Question about irq_tables.c. Many of the CS5536 systems have a write_pirq_routing_table() in irq_tables.c that sets the steering registers. I'd like to be able to set the steering registers in CS5530 systems too, but I'm not a software developer and I need some help. So in src/mainboard/artecgroup/dbe61/irq_tables.c, you have:
/* Set up chipset IRQ steering. */ pciAddr = 0x80000000 | (CHIPSET_DEV_NUM << 11) | 0x5C; chipset_irq_map = (PIRQD << 12 | PIRQC << 8 | PIRQB << 4 | PIRQA); printk_debug("%s(%08X, %04X)\n", __FUNCTION__, pciAddr, chipset_irq_map); outl(pciAddr & ~3, 0xCF8); outl(chipset_irq_map, 0xCFC);My main question with this block of code is what the two outl() calls are for. It looks like pciAddr gets the address of the 0x5c steering register, and chipset_irq_map sets the right bits to set all 4 PIRQ lines. But I'd expect to see the chipset_irq_map written to pciAddr.
As an alternative, Kenji Noguchi used this code block to set the registers in a CS5530 system he's working on (posted 5-May-2007): device_t pdev; //CS5530A pdev = dev_find_slot(0, (0x12 << 3) + 0); pci_write_config8(pdev, 0x5c, 0xab); pci_write_config8(pdev, 0x5d, 0x09);
This block makes more sense to me. Obviously the register values could be set by #defines, but it looks simpler to me.
Bottom line is, before I implement IRQ steering for my CS5530 system, I want to understand what the first code block is doing, and if (or why) it's preferable over the 2nd code block. Any guidance is appreciated.
thanks, Jonathan
outl(pciAddr & ~3, 0xCF8); outl(chipset_irq_map, 0xCFC)
is basically the same as
pci_write_config8(pdev, 0x5c, 0xab); pci_write_config8(pdev, 0x5d, 0x09);
CFC/CF8 is the PCI config space.
Ahhh... thanks Marc, that was the clarification I needed.
With that in mind, that block of code should work directly with the CS5530 after defining CHIPSET_DEV_NUM appropriately. What about '0x80000000', is that a common base address applicable to all CS553x systems?
thanks, Jonathan
DEV_NUM should be a constant for the 5530. It is always hooked up on the same IDSEL. The 0x80000000 is standard for all i/o based PCI config accesses. It indicates that it is a config access and not just a normal PCI i/o access.
Marc
Marc, I've implemented the CS5536-style IRQ steering register code from above in my CS5530 system. This is what I'm using: /* Set up chipset IRQ steering. */ pciAddr = 0x80000000 | (0x12 << 11) | 0x5C; chipset_irq_map = (PIRQD << 12 | PIRQC << 8 | PIRQB << 4 | PIRQA); printk_debug("%s(%08X, %04X)\n", __FUNCTION__, pciAddr, chipset_irq_map); outl(pciAddr & ~3, 0xCF8); outl(chipset_irq_map, 0xCFC);
However, it doesn't seem to have worked entirely. If it had worked, I assume I should be able to boot a standard Linux kernel and have IRQs worked for the devices in the PIRQ table. Instead, these devices don't work, unless I boot a kernel with the CS5530 IRQ router patch. In the LB output, you get this from write_pirq_routing_table():
write_pirq_routing_table(8000905C, 99BA)
...which I think is right. It doesn't seem like there's much that could be wrong here. Are the the steering bits reversed maybe? The high 8 bits are for PIRQD and C, so that would screw things up if they were written to 0x5C, which is the INTB/INTA register. Is there a reliable way to see the settings of the steering bits from a running system?
thanks, Jonathan
____________________________________________________________________________________ Boardwalk for $500? In 2007? Ha! Play Monopoly Here and Now (it's updated for today's economy) at Yahoo! Games. http://get.games.yahoo.com/proddesc?gamekey=monopolyherenow
Jonathan Sturges wrote:
----- Original Message ---- From: Marc Jones marc.jones@amd.com To: Jonathan Sturges jonathansturges@yahoo.com Cc: LinuxBIOS mailing list linuxbios@linuxbios.org Sent: Tuesday, September 25, 2007 12:05:19 PM Subject: Re: [LinuxBIOS] Two more CS5530 IRQ steering questions
Jonathan Sturges wrote:
Jonathan Sturges wrote: Two additional questions about CS5530 IRQ steering:
Comments from Uwe Hermann and Peter Stuge have indicated that it's really better for the kernel to setup the steering registers. Why is this? It sounds like the BIOS is a good place to set these. I assume that a knowledgeable OS could change them if necessary? At the very least, it does sound like we all agree that it's OK to have LB setup the steering until Linux is fixed.
Question about irq_tables.c. Many of the CS5536 systems have a write_pirq_routing_table() in irq_tables.c that sets the steering registers. I'd like to be able to set the steering registers in CS5530 systems too, but I'm not a software developer and I need some help. So in src/mainboard/artecgroup/dbe61/irq_tables.c, you have:
/* Set up chipset IRQ steering. */ pciAddr = 0x80000000 | (CHIPSET_DEV_NUM << 11) | 0x5C; chipset_irq_map = (PIRQD << 12 | PIRQC << 8 | PIRQB << 4 | PIRQA); printk_debug("%s(%08X, %04X)\n", __FUNCTION__, pciAddr, chipset_irq_map); outl(pciAddr & ~3, 0xCF8); outl(chipset_irq_map, 0xCFC);My main question with this block of code is what the two outl() calls are for. It looks like pciAddr gets the address of the 0x5c steering register, and chipset_irq_map sets the right bits to set all 4 PIRQ lines. But I'd expect to see the chipset_irq_map written to pciAddr.
As an alternative, Kenji Noguchi used this code block to set the registers in a CS5530 system he's working on (posted 5-May-2007): device_t pdev; //CS5530A pdev = dev_find_slot(0, (0x12 << 3) + 0); pci_write_config8(pdev, 0x5c, 0xab); pci_write_config8(pdev, 0x5d, 0x09);
This block makes more sense to me. Obviously the register values could be set by #defines, but it looks simpler to me.
Bottom line is, before I implement IRQ steering for my CS5530 system, I want to understand what the first code block is doing, and if (or why) it's preferable over the 2nd code block. Any guidance is appreciated.
thanks, Jonathan
outl(pciAddr & ~3, 0xCF8); outl(chipset_irq_map, 0xCFC)
is basically the same as
pci_write_config8(pdev, 0x5c, 0xab); pci_write_config8(pdev, 0x5d, 0x09);
CFC/CF8 is the PCI config space.
Ahhh... thanks Marc, that was the clarification I needed.
With that in mind, that block of code should work directly with the CS5530 after defining CHIPSET_DEV_NUM appropriately. What about '0x80000000', is that a common base address applicable to all CS553x systems?
thanks, Jonathan
DEV_NUM should be a constant for the 5530. It is always hooked up on the same IDSEL. The 0x80000000 is standard for all i/o based PCI config accesses. It indicates that it is a config access and not just a normal PCI i/o access.
Marc
Marc, I've implemented the CS5536-style IRQ steering register code from above in my CS5530 system. This is what I'm using: /* Set up chipset IRQ steering. */ pciAddr = 0x80000000 | (0x12 << 11) | 0x5C; chipset_irq_map = (PIRQD << 12 | PIRQC << 8 | PIRQB << 4 | PIRQA); printk_debug("%s(%08X, %04X)\n", __FUNCTION__, pciAddr, chipset_irq_map); outl(pciAddr & ~3, 0xCF8); outl(chipset_irq_map, 0xCFC);
However, it doesn't seem to have worked entirely. If it had worked, I assume I should be able to boot a standard Linux kernel and have IRQs worked for the devices in the PIRQ table. Instead, these devices don't work, unless I boot a kernel with the CS5530 IRQ router patch. In the LB output, you get this from write_pirq_routing_table():
write_pirq_routing_table(8000905C, 99BA)
...which I think is right. It doesn't seem like there's much that could be wrong here. Are the the steering bits reversed maybe? The high 8 bits are for PIRQD and C, so that would screw things up if they were written to 0x5C, which is the INTB/INTA register. Is there a reliable way to see the settings of the steering bits from a running system?
thanks, Jonathan
Jonathan,
You can use lspci to get that information. "lspci -xxxv" or "lspci -s 00:12.0 -xxxv" for just device 0x12
Marc