This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TCAN4550: TCAN4550RGYR bootup issue.

Part Number: TCAN4550

Hi,

We are trying to bring up the tcan4x5x.c driver in Linux kernel-4.1.15. 

Downloaded tcan4x5x.c driver from below link,

Link: git.kernel.org/.../m_can 

We are getting below errors, while booting,

spi_imx 2008000.ecspi: probed
CAN device driver interface
tcan4x5x spi0.0: Could not get Message RAM configuration.
tcan4x5x: probe of spi0.0 failed with error -12

our DTS file shown below,

&ecspi1 {
        fsl,spi-num-chipselects = <1>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_ecspi1_1>;
        cs-gpios = <&gpio4 26 0>;
        status = "okay";

        tcan4x5x: tcan4x5x@0 {
                compatible = "ti,tcan4x5x";
                reg = <0>;
                #address-cells = <1>;
                #size-cells = <1>;
                spi-max-frequency = <10000000>;
                clock-names = "hclk", "cclk";
                bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
                interrupt-parent = <&gpio1>;
                interrupts = <23 GPIO_ACTIVE_LOW>;
                reset-gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
                status = "okay";
        };
};

Note: We are not sure "bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;" is proper.

FYI, we confirmed SPI (Clock, MOSI) lines are proper. verified by enabling spidev.c driver.

Requesting you to provide a support to fix this issue.

Regards,
Haji

  • Hello Haji,

    The tcan4x5x.c driver has been adopted into the Linux Kernel and is generally supported by the Linux community.  This forum is primarily for the TCAN4550 device parameter and physical layer support with the hardware itself and not necessarily for Linux firmware debug support.

    However, I have looked through your Device Tree Source code and it looks very similar to the example code found in the Bosch MCAN controller Device Tree Bindings Documentation which I am copying below for the benefit of the thread.

    Bosch MCAN controller Device Tree Bindings
    -------------------------------------------------
    
    Required properties:
    - compatible		: Should be "bosch,m_can" for M_CAN controllers
    - reg			: physical base address and size of the M_CAN
    			  registers map and Message RAM
    - reg-names		: Should be "m_can" and "message_ram"
    - interrupts		: Should be the interrupt number of M_CAN interrupt
    			  line 0 and line 1, could be same if sharing
    			  the same interrupt.
    - interrupt-names	: Should contain "int0" and "int1"
    - clocks		: Clocks used by controller, should be host clock
    			  and CAN clock.
    - clock-names		: Should contain "hclk" and "cclk"
    - pinctrl-<n>		: Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt
    - pinctrl-names 	: Names corresponding to the numbered pinctrl states
    - bosch,mram-cfg	: Message RAM configuration data.
    			  Multiple M_CAN instances can share the same Message
    			  RAM and each element(e.g Rx FIFO or Tx Buffer and etc)
    			  number in Message RAM is also configurable,
    			  so this property is telling driver how the shared or
    			  private Message RAM are used by this M_CAN controller.
    
    			  The format should be as follows:
    			  <offset sidf_elems xidf_elems rxf0_elems rxf1_elems
    			   rxb_elems txe_elems txb_elems>
    			  The 'offset' is an address offset of the Message RAM
    			  where the following elements start from. This is
    			  usually set to 0x0 if you're using a private Message
    			  RAM. The remain cells are used to specify how many
    			  elements are used for each FIFO/Buffer.
    
    			  M_CAN includes the following elements according to user manual:
    			  11-bit Filter	0-128 elements / 0-128 words
    			  29-bit Filter	0-64 elements / 0-128 words
    			  Rx FIFO 0	0-64 elements / 0-1152 words
    			  Rx FIFO 1	0-64 elements / 0-1152 words
    			  Rx Buffers	0-64 elements / 0-1152 words
    			  Tx Event FIFO	0-32 elements / 0-64 words
    			  Tx Buffers	0-32 elements / 0-576 words
    
    			  Please refer to 2.4.1 Message RAM Configuration in
    			  Bosch M_CAN user manual for details.
    
    Optional Subnode:
    - can-transceiver	: Can-transceiver subnode describing maximum speed
    			  that can be used for CAN/CAN-FD modes. See
    			  Documentation/devicetree/bindings/net/can/can-transceiver.txt
    			  for details.
    Example:
    SoC dtsi:
    m_can1: can@20e8000 {
    	compatible = "bosch,m_can";
    	reg = <0x020e8000 0x4000>, <0x02298000 0x4000>;
    	reg-names = "m_can", "message_ram";
    	interrupts = <0 114 0x04>,
    		     <0 114 0x04>;
    	interrupt-names = "int0", "int1";
    	clocks = <&clks IMX6SX_CLK_CANFD>,
    		 <&clks IMX6SX_CLK_CANFD>;
    	clock-names = "hclk", "cclk";
    	bosch,mram-cfg = <0x0 0 0 32 0 0 0 1>;
    };
    
    Board dts:
    &m_can1 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&pinctrl_m_can1>;
    	status = "enabled";
    
    	can-transceiver {
    		max-bitrate = <5000000>;
    	};
    };

    From your code:
    bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;

    This looks like you want 32 Rx FIFO 0 elements, 1 Tx Event FIFO element, and 1 Tx Buffer element. With the exception of the additional Tx Event FIFO element, this appears just as the example configuration and I believe should be ok.  I have seen some information that mentioned at one point the Tx Event FIFO was not supported in the Kernel, but this could be dated information and support for this could now be supported.  I will admit, I'm not an expert on this and am just sharing what I have seen.  However, I don't believe this value is what is causing your issue regardless of whether the Tx Event FIFOs are currently supported or not.

    I noticed that your receiving a -12 error and if I am correct, the Linux -12 error is the "ENOMEM" or "Out of Memory" error that is getting thrown from the fwnode_property_read_u32_array function of the following code.  If I understand this correctly, it is attempting to pull your mram-cfg values you defined in the DTS file and store them into the mram_config_vals memory allocation. 

    struct m_can_classdev *m_can_class_allocate_dev(struct device *dev)
    {
    	struct m_can_classdev *class_dev = NULL;
    	u32 mram_config_vals[MRAM_CFG_LEN];
    	struct net_device *net_dev;
    	u32 tx_fifo_size;
    	int ret;
    
    	ret = fwnode_property_read_u32_array(dev_fwnode(dev),
    					     "bosch,mram-cfg",
    					     mram_config_vals,
    					     sizeof(mram_config_vals) / 4);
    	if (ret) {
    		dev_err(dev, "Could not get Message RAM configuration.");
    		goto out;
    	}
    
    	/* Get TX FIFO size
    	 * Defines the total amount of echo buffers for loopback
    	 */
    	tx_fifo_size = mram_config_vals[7];
    
    	/* allocate the m_can device */
    	net_dev = alloc_candev(sizeof(*class_dev), tx_fifo_size);
    	if (!net_dev) {
    		dev_err(dev, "Failed to allocate CAN device");
    		goto out;
    	}
    
    	class_dev = netdev_priv(net_dev);
    	if (!class_dev) {
    		dev_err(dev, "Failed to init netdev cdevate");
    		goto out;
    	}
    
    	class_dev->net = net_dev;
    	class_dev->dev = dev;
    	SET_NETDEV_DEV(net_dev, dev);
    
    	m_can_of_parse_mram(class_dev, mram_config_vals);
    out:
    	return class_dev;
    }
    EXPORT_SYMBOL_GPL(m_can_class_allocate_dev);

    I also noticed that the "reg" parameter of our DTS file is set to <0> which I think might be a problem or something you might want to check into.  From my understanding of this property, this is the physical base address and size of the M_CAN registers map and Message RAM.  I see in the example code from the documentation that they set both a base address and a size allocation while your code does not.

    This makes me question whether your "out of memory" error code could be the result of not having allocated any actual memory.  Once again I'm not an expert on the Linux driver code and I don't have a complete knowledge of how all of this code operates, but a difference in the memory allocation code and an out of memory error message seemed to be too convenient to point out.

    Regards,

    Jonathan

  • Hello Jonathan,

    I also noticed that the "reg" parameter of our DTS file is set to <0> which I think might be a problem or something you might want to check into.  From my understanding of this property, this is the physical base address and size of the M_CAN registers map and Message RAM.  I see in the example code from the documentation that they set both a base address and a size allocation while your code does not.

    Haji-> We referred below tcan4x5x.txt Documentation file to create a dts file entry for tcan4x5x.c driver, as shown below

    Texas Instruments TCAN4x5x CAN Controller
    ================================================

    This file provides device node information for the TCAN4x5x interface contains.

    Required properties:
            - compatible: "ti,tcan4x5x"
            - reg: 0
            - #address-cells: 1
            - #size-cells: 0
            - spi-max-frequency: Maximum frequency of the SPI bus the chip can
                                 operate at should be less than or equal to 18 MHz.
            - device-wake-gpios: Wake up GPIO to wake up the TCAN device.
            - interrupt-parent: the phandle to the interrupt controller which provides
                        the interrupt.
            - interrupts: interrupt specification for data-ready.

    See Documentation/devicetree/bindings/net/can/m_can.txt for additional
    required property details.

    Optional properties:
            - reset-gpios: Hardwired output GPIO. If not defined then software
                           reset.
            - device-state-gpios: Input GPIO that indicates if the device is in
                                  a sleep state or if the device is active.

    Example:
    tcan4x5x: tcan4x5x@0 {
                    compatible = "ti,tcan4x5x";
                    reg = <0>;
                    #address-cells = <1>;
                    #size-cells = <1>;
                    spi-max-frequency = <10000000>;
                    bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
                    interrupt-parent = <&gpio1>;
                    interrupts = <14 GPIO_ACTIVE_LOW>;
                    device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
                    device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
                    reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
    };

    Regards,
    Haji

  • Hello Haji,

    Good point, I should have also referenced that file as well in my original post and since you followed the example, I do not think the issue is with the settings you have used. 

    I believe that the error code 12 you are receiving is referring to the processor not being able to allocate memory to store the retrieved settings from this file.  Since that is not an issue specific to communication with the TCAN4550 device in hardware and is part of the boot process, I would check with how your memory is being allocated.

    Regards,

    Jonathan

  • Dear Jonathan,

    Instead of reading the "bosch,mram-cfg" entry in dts file from tcan4x5x.c driver,hard-coded the value directly to the driver as given below to avoid "tcan4x5x spi0.0: Could not get Message RAM configuration" error.

    #if 0    //Commented 
    ret = fwnode_property_read_u32_array(dev_fwnode(dev),
    	"bosch,mram-cfg",
    	mram_config_vals,
    	sizeof(mram_config_vals) / 4);
    if (ret) {
    	dev_err(dev, "Could not get Message RAM configuration.");
            goto out;
    }
    
    #endif
            mram_config_vals[0] = 0;
            mram_config_vals[1] = 0;
            mram_config_vals[2] = 0;
            mram_config_vals[3] = 32;
            mram_config_vals[4] = 0;
            mram_config_vals[5] = 0;
            mram_config_vals[6] = 1;
            mram_config_vals[7] = 1;

    After doing above changes, we are facing following errors while booting,

    tcan4x5x spi0.0: Unsupported version number: 0
    tcan4x5x spi0.0: Probe failed, err=-22
    tcan4x5x: probe of spi0.0 failed with error -22

    FYI, when we tried to read the mcan register, the return value is always "0". example given below,

    int read_xidam = tcan4x5x_read_reg(mcan_class, 90);

    Please let us know where we went wrong.

     

    Thanks & Regards,

    Haji

  • Hello Haji,

    In your original post you stated that you were using Linux Kernel version 4.1.15.  I suspect this may be related to a compatibility issue between the drivers and the version of the Kernel you are using. 

    The drivers were released with Kernel version 5.4.  Some driver modifications may be needed to properly back-port to this previous kernel version.  As an example, I believe you can find a version that was back-ported to 4.14 here:

    I do not know of any version that has been back-ported to a version older than 4.14.  Could you try using a newer version of the kernel?

    Regards,

    Jonathan

  • Dear Jonathan,

    Ported tcan4x5x.c driver to 4.19.21 Linux kernel.  Still we are facing below errors,

    tcan4x5x spi0.0: Unsupported version number: 0
    tcan4x5x spi0.0: Probe failed, err=-22
    tcan4x5x: probe of spi0.0 failed with error -22

    FYI,
    When driver trying to read MCAN register to get the Mcan version(m_can_check_core_release) spi clock is not pulsing, checked with oscilloscope.

    Regards,
    Haji

  • Hello Haji,

    It certainly appears that there is a problem with your SPI configuration which is preventing communication with the TCAN4550 device.  This could be an error with your SPI and or Clock configuration.  How are you configuring your SPI and Clocks?  Are you doing that through the device tree as well?  Can you verify those are configured properly? I haven't seen that portion of your code.

    If you believe those are configured properly, is it possible for you to do any form of manual SPI communications?  If you can, we could try to read and write to a register in the TCAN4550 as a way to test if the TCAN4550 is able to communicate and eliminate the TCAN4550 hardware as a potential error source.

    Also, what is your hardware platform you are using?  Is this standard development platform such as the BeagleBone Black, Raspberry PI, etc.?  If so, are you using the TCAN4550EVM or BOOST-XL-CANFD boards for the TCAN4550?  Or have you developed your own board?

    Regards,

    Jonathan

  • Dear Jonathan,

    Please find our replies below,

    It certainly appears that there is a problem with your SPI configuration which is preventing communication with the TCAN4550 device.  This could be an error with your SPI and or Clock configuration.  How are you configuring your SPI and Clocks?  Are you doing that through the device tree as well?  Can you verify those are configured properly? I haven't seen that portion of your code.

    Haji -> Below is the dts configuration done for TCAN4550 in our linux kernel

    clocks {
     hclk: clock@4 {
      compatible = "fixed-clock";
      reg = <3>;
      #clock-cells = <0>;
      clock-frequency = <40000000>;
      clock-output-names = "hclk";
     };
     cclk: clock@5 {
      compatible = "fixed-clock";
      reg = <3>;
      #clock-cells = <0>;
      clock-frequency = <40000000>;
      clock-output-names = "cclk";
     };
    };
    &ecspi1 {
            fsl,spi-num-chipselects = <1>;
            cs-gpios = <&gpio4 26 0>;
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_cs>;
            status = "okay";
    
            tcan4x5x: tcan4x5x@0 {
                    compatible = "ti,tcan4x5x";
                    reg = <0>;
                    #address-cells = <1>;
                    #size-cells = <1>;
                    spi-max-frequency = <10000000>;
                    bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
                    clocks = <&hclk>, <&cclk>;
                    clock-names = "hclk", "cclk";
                    status = "okay";
            };
    };
    

    Note:  cclk & hclk clock has  been present in driver which is not support by imx6ull platform. so enabled the clock as shown above. Is this configuration is correct ?

    If you believe those are configured properly, is it possible for you to do any form of manual SPI communications?  If you can, we could try to read and write to a register in the TCAN4550 as a way to test if the TCAN4550 is able to communicate and eliminate the TCAN4550 hardware as a potential error source.

    Haji ->  Verified SPI (CLOCK & MOSI) lines by enabling Spidev driver.  Since MISO was probing, didn't do register Read/ Write for TCAN4550. Does verifying test is needed still ?

    Also, what is your hardware platform you are using?  Is this standard development platform such as the BeagleBone Black, Raspberry PI, etc.?  If so, are you using the TCAN4550EVM or BOOST-XL-CANFD boards for the TCAN4550?  Or have you developed your own board?

    Haji -> Yes, our platform is custom platform based on IMX6ULL. Also we are using TCAN4550EVM boards.

    Regards,
    Haji

  • Haji,

    Thank you for your patience, due to US holiday some responses will be delayed. We will get back to you by the end of the week.

    Regards,

  • Haji,

    Yes, the CLK and SCLK configurations look fine in terms of the assignment and rates used. I think the SPI verification test is still useful, to verify that data is being correctly sent into and out of the TCAN4550.

    Regards,