The FreeBSD FDT, the Raspberry PI SPI

How the FDT works

In specific, I'm looking at this file bcm2835.dtsi which contains the hardware definitions for the BCM2835, the SOC which powers a Raspberry Pi. Primarily, i'm interested in how to read it.   To really make sense of this, you should have this pdf at hand; it's the hardware manual for BCM2835.  If you're interested the FreeBSD code for OpenFirmware is here.

devicetree.org has a pretty good explanation of how to read a dts file, here.

Looking at the start of the BCM2835 dts, I see this:

cpus {
  cpu@0 {
    compatible = "arm,1176jzf-s";
  };
};

This defines the CPU with the syntax "<manufacturer, model>.  So the BCM2835 has an ARM CPU and the model is "1176jzf-s".

Next I see:

SOC: axi {
   compatible = "simple-bus";
   #address-cells = <1>;
   #size-cells = <1>;
   reg = <0x20000000 0x01000000>;
   ranges = <0 0x20000000 0x01000000>;

This defines an axi bus, which is compatible with the FreeBSD simple-bus.

These two lines:

 #address-cells = <1>;
 #size-cells = <1>;

Describe that an address cell is 32 bits wide, and that size cells are also 32 bits wide.

This line

reg = <0x20000000 0x01000000>;

describes that the axi bus is memory mapped to the memory range at address 0x20000000  and that the memory range is 0x01000000 bytes wide.

So, looking at some peripherals, I see this for the gpio

reg = <0x200000 0xb0>;

So the gpio is at address 0x200000 within the range specified for the bus, and is 0xb0 cells wide (176, 32-bit bytes).  This is consistent with page 90-91 of the BCM2835 PDF.  Note that the PDF gives the memory range as starting at 0x7E200000.  The PDF specifies memory addresses as bus addresses, but the FDT specifies them as physical addresses.  Page 5 of the PDF explains the difference with a diagram.  Section 1.2.4 on  page 6 of the PDF explains that bus addresses are used in the pdf.

The SPI

The SPI base address is specified on page 152 of the PDF.  It's as bus address 0x7E204000 and its 6 - 32bit cells wide. So, an appropriate declaration for SPI0, in polled mode, could look like:

spio0 {
	compatible = "broadcom,bcm2835-spi";
	reg = <0x204000 0x06>;
};

 

Leave a Reply