Using VxWorks 7 VxBus device-specific parameters

Add flexibility to your driver configuration using device-specific parameters.

A couple of years ago we developed a VxWorks 7 BSP for the Renesas R-Car H3 SIP evaluation board. This included developing drivers for the main SoC interfaces: serial, Ethernet, MMC, I2C, GPIO and PCI Express. 

I wrote the PCI Express controller driver and I tested it by plugging an Intel i210 PCIe card into the PCIe slot on the R-Car H3 evaluation board. I then added the VxWorks 7 Intel gigabit Ethernet driver to the kernel image and confirmed the i210 device was found. The i210 was connected to the network stack and used as a second Ethernet interface on the board. 

The BSP was used by our development team in Leamington and by our customer’s teams at various locations across the globe. One day we received a problem report saying that a PCIe CAN controller was not being initialised when the target system booted. A little investigation revealed that the link between the PCIe root complex and the PCIe endpoint was not being established.

The PCIe controller driver had a hard-coded link establishment timeout of 1 ms but the link with the CAN controller card needed up to 5 ms to establish reliably. The easy thing to do would have been to increase the timeout to some larger value but if no PCIe peripheral were present this would needlessly increase the boot time.

The solution was to make the link timeout a device-specific parameter that could be set in the device tree for the board if the default timeout was insufficient for a particular use case.

Driver changes to use device-specific parameters

The first step was to update the driver to make the link activation timeout a driver parameter. To do this we had to create a parameter table that contained the default value the driver should use:

/* 
 * R-Car H3 PCIe controller driver parameter table 
 */  
LOCAL VXB_PARAMS rcarH3PcieParams[] = 
    { 
    { DLLACT_TIMEOUT_PARAM, VXB_PARAM_INT32, { (void *)DLLACT_TIMEOUT_US } }, 
    { NULL, VXB_PARAM_END_OF_LIST, { NULL } } 
    };

Then we updated the device definition to indicate there was a parameter table by using the VXB_DRVFLAG_PARAM flag.

/* 
 * R-Car H3 PCIe controller VxBus driver definition 
 */ 
VXB_DRV vxbFdtRcarH3PcieDrv = 
    { 
    { NULL } ,                          /* list node */ 
    RCAR_H3_PCIE_DRV_NAME,              /* Name */ 
    "Renesas R-Car H3 PCIe driver",     /* Description */ 
    VXB_BUSID_FDT,                      /* Class */ 
    VXB_DRVFLAG_PARAM,                  /* Flags */ 
    0,                                  /* Reference count */ 
    rcarH3PcieMethodList,               /* Method table */ 
    rcarH3PcieParams                    /* parameter defaults */ 
    };

The driver initialisation code was updated to get this parameter, as shown below:

/* 
 * Get the DLL activation timeout from the driver parameter table 
 */  
if (vxbParamGet (pDev, 
                 DLLACT_TIMEOUT_PARAM, 
                 VXB_PARAM_INT32, 
                 &param) == OK) 
    { 
    dllActTimeoutUs = (unsigned)param.int32Val; 
    } 
else 
    { 
    PCIEC_DBG (PCIEC_DBG_ERR, 
               "%s: pDev %p: Failed to get DLL timeout parameter " 
               "- using default\n", 
               __FUNCTION__, pDev); 
    }

The driver used the parameter value taken from the driver parameter table unless a value was provided in the device tree to override this default.

Device tree device-specific parameter override

The final step was to add a new section to the device tree to update this parameter. This was done by creating a devparam section in the chosen clause of the device tree. The following device tree extract is the example given in the VxWorks 7 documentation:

chosen node example: 
    chosen { 
        .... 
        devparam 
            { 
            <devName>@<devUnit> 
                { 
                <parameter name> = <parameter value>; 
                ....
                }; 
             ....
             };

The chosen node can includes parameters for any device. The deviceName and deviceUint are used to match the device when overriding a default parameter value.

Using this as a guide we updated the R-Car H3 device tree to provide longer link activation timeout value (5000 microseconds):

chosen 
    { 
    /* U-Boot bootm command will update bootargs in standalone DTB */ 
    bootargs = "etherAvb(0,0) host:vxWorks h=192.168.0.2 e=192.168.0.20 u=target pw=vxTarget"; 

    devparam 
        { 
        renesas,rcar-h3-pcie@0 
            { 
            dllActTimeoutUs = <5000>; 
            }; 
        }; 
    }; 
};

With the device tree change in place and no card present in the PCIe slot on the R-Car evaluation board we saw the following debug output:

rcarH3PcieHwInit: pDev 0xffff80000011f980: PCIe DLL not ready after 5000us 
rcarH3PcieAttach: pDev 0xffff80000011f980: error exit

With this update in place the team using the PCIe CAN controller was able to set an appropriate link establishment timeout for their hardware configuration by updating the device tree on their target system.

Device-specific parameters are a flexible way of supporting different hardware configurations and avoid relying on hard-coded values that might not be suitable for some target systems.

More information can be found in the section VxBus Driver Tunables in the VxWorks 7 BSP and Driver Guide.