MPC5200:PCI

From FDTWiki

Jump to: navigation, search

Contents

MPC5200 PCI Host Bridge

In this section we'll look into the description of a Host/PCI bridge. We use the Freescale lite5200b board as an example, because you will find the schematics in the Internet. To understand this section you need some very basic knowledge of PCI. This is NOT a tutorial about PCI, if you need some more in depth information, please read[1]. For the complete documentation of the Open Firmware PCI bindings please look into PCI Bus Binding to Open Firmware.

/ {
	model = "fsl,lite5200b";
	compatible = "fsl,lite5200b";
	#address-cells = <1>;
	#size-cells = <1>;
	interrupt-parent = <&mpc5200_pic>;

	soc5200@f0000000 {
		...
		mpc5200_pic: interrupt-controller@500 {
			// 5200 interrupts are encoded into two levels;
			interrupt-controller;
			#interrupt-cells = <3>;
			compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
			reg = <0x500 0x80>;
		};
		...
	};

	pci@f0000d00 {
		#interrupt-cells = <1>;
		#size-cells = <2>;
		#address-cells = <3>;
		device_type = "pci";
		compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
		reg = <0xf0000d00 0x100>;
		interrupt-map-mask = <0xf800 0 0 7>;
		interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
				 0xc000 0 0 2 &mpc5200_pic 1 1 3
				 0xc000 0 0 3 &mpc5200_pic 1 2 3
				 0xc000 0 0 4 &mpc5200_pic 1 3 3

				 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
				 0xc800 0 0 2 &mpc5200_pic 1 2 3
				 0xc800 0 0 3 &mpc5200_pic 1 3 3
				 0xc800 0 0 4 &mpc5200_pic 0 0 3>;
		clock-frequency = <0>; // From boot loader
		interrupts = <2 8 0 2 9 0 2 10 0>;
		bus-range = <0 0>;
		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
			  0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
			  0x01000000 0 0x00000000 0xb0000000 0 0x01000000;
	};
};

Now we will go through the different PCI specific properties, the common properties are already described above.

Common HOST/PCI bridge Properties

The the first number of the bus-range property denotes the PCI bus number this node is responsible for, the second number is the largest bus number of any PCI bus that is subordinate to this node. Because we only have the Host/PCI bridge in our example, we have only one PCI bus so: bus-range = <0 0>.

device_type = "pci" is self-explanatory.

The interrupts = <2 8 0 2 9 0 2 10 0>; property describes the interrupts the host/PCI-bridge may trigger. Don't mix up these interrupts with interrupts PCI devices might trigger (using INTA, INTB, ...). These are described later in the section PCI Interrupt Mapping. Looking into[2] shows that the bridge may trigger three interrupts: 8, 9, 10; all of the peripheral interrupt group and level high sensitive. This triple of interrupt group, interrupt number and sensitivity is the reason why we have an #interrupt-cells = <3>; property in the mpc5200_pic node for the MPX5200B programmable interrupt controller.

PCI Address Translation

The PCI address space is completely separate from the CPU address space, so we need to specify some kind of address translation. As always, this is done using the range property. The child addresses (PCI addresses) consist of three cells as specified in the #address-cells = <3>; property. The first question might be, why do we need three 32 bit cells to specify a PCI address. The three cells are labeled phys.hi, phys.mid and phys.low [3].

  • phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr
  • phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
  • phys.low cell: llllllll llllllll llllllll llllllll

PCI is specified up to 64 bit addresses, which are denoted in phys.mid and phys.low. The really interesting things are in phys.high:

  • n: relocatable region (doesn't play a role here)
  • p: this range defines a prefetchable memory region
  • t: aliased address (doesn't play a role here)
  • ss: space code
    • 00: configuration space
    • 01: I/O space
    • 10: 32 bit memory space
    • 11: 64 bit memory space
  • bbbbbbbb: The PCI bus number. PCI may be structured hierarchically. So we may have PCI/PCI bridges which will define sub busses.
  • ddddd: The device number. The device number is typically formed by the IDSEL PCI line. We will talk about the device number later if we go through the interrupt map property.
  • fff: The function number. Only used if we have a multifunction PCI device.
  • rrrrrrrr: The PCI register to be addressed.

So looking onto our ranges property, we have three regions:

  • a 32 bit prefetchable memory region beginning on PCI address 0x80000000 of 512 MByte size which will be mapped onto address 0x80000000 on the host CPU.
  • a 32 bit non-prefetchable memory region beginning on PCI address 0xa0000000 of 256 MByte size which will be mapped onto address 0xa0000000 on the host CPU.
  • an I/O region beginning on PCI address 0x00000000 of 16 MByte size which will be mapped onto address 0xb0000000 on the host CPU.

PCI Interrupt Mapping

Now we come to the most interesting part, PCI interrupt mapping. A PCI device can trigger interrupts using the wires #INTA, #INTB, #INTC and #INTD. If we don't have multifunction PCI devices, a device is obligated to use #INTA for interrupts. Because on PCI only the interrupt number is of interest, we have the property #interrupt-cells = <1>; in our PCI node.

In our example board, we have 2 PCI slots with 4 interrupt lines, respectively, so we have to map 8 interrupt lines to the PIC in the MPC5200B. This is done using the interrupt-map property. The exact procedure for interrupt mapping is described in[4] .

Because the interrupt number (#INTA etc.) is not sufficient to distinguish between several PCI devices on a single PCI bus, we also have to denote which PCI device triggered the interrupt line. Fortunately, every PCI device has a unique device number that we can use for. To distinguish between interrupts of several PCI devices we need a tuple consisting of the PCI device number and the PCI interrupt number. Speaking more generally, we construct a unit interrupt specifier which has four cells:

  • three #address-cells consisting of phys.hi, phys.mid, phys.low, and
  • one #interrupt-cell (#INTA, #INTB, #INTC, #INTD).

Because we only need the device number part of the PCI address, the interrupt-map-mask property comes into play. interrupt-map-mask is also a 4-tuple like the unit interrupt specifier. The 1's in the mask denote which part of the unit interrupt specifier should be taken into account. In our example we can see that only the device number part of phys.hi is required and we need 3 bits to distinguish between the four interrupt lines (Counting PCI interrupt lines start at 1, not at 0!).

Now we can construct the interrupt-map property. This property is a table and each entry in this table consists of a child (PCI bus) unit interrupt specifier, a parent handle (the interrupt controller which is responsible for serving the interrupts) and a parent unit interrupt specifier. So in the first line we can read that the PCI interrupt #INTA is mapped onto group 0, IRQ0, level low sensitive of our MPC5200B PIC[5].

The only missing part for now are the weird numbers int the PCI bus unit interrupt specifier. Now we have to look into the schematics[6] of the Lite5200b board. Here you can see that the IDSEL line of PCI slot 1 is tied to PCI address line 24 and the IDSEL line of PCI slot 2 to PCI address line 25[7]. The IDSEL lines are used to determine the PCI device number. Looking into[8] shows that using AD24 for IDSEL results in a device number of 0b11000 and AD25 will form a device number of 0b11001. Using these device numbers for the phys.hi word gives us:

  • phys.hi for slot 1 is 0xC000, and
  • phys.hi for slot 2 is 0xC800.

Putting it all together the interrupt-map property shows:

  • #INTA of slot 1 is group 0, IRQ0, level low sensitive on the MPC5200B PIC
  • #INTB of slot 1 is group 1, IRQ1, level low sensitive on the MPC5200B PIC
  • #INTC of slot 1 is group 1, IRQ2, level low sensitive on the MPC5200B PIC
  • #INTD of slot 1 is group 1, IRQ3, level low sensitive on the MPC5200B PIC

and

  • #INTA of slot 2 is group 1, IRQ1, level low sensitive on the MPC5200B PIC
  • #INTB of slot 2 is group 1, IRQ2, level low sensitive on the MPC5200B PIC
  • #INTC of slot 2 is group 1, IRQ3, level low sensitive on the MPC5200B PIC
  • #INTD of slot 2 is group 0, IRQ0, level low sensitive on the MPC5200B PIC

Notes

  1. Tom Shanley / Don Anderson: PCI System Architecture. Mindshare Inc.
  2. MPC5200B User’s Manual Page 7-7
  3. PCI Bus Bindings to Open Firmware.
  4. Open Firmware Recommended Practice: Interrupt Mapping
  5. PCI interrupts are always level low sensitive.
  6. Lite5200B Evaluation Board
  7. It is common practice to use upper address lines to serve IDSEL wires.
  8. MPC5200B User’s Manual Page 10-69 and 10-70
Personal tools