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.

DCAN0 doesn't work when board is cold started

Hello,

I am using a DRA7xx EVM based board. When the board is powered up, the DCAN0 doesn't work at all. DCAN0 CTL register always shows a 0xF which indicating it is in initialization mode. After I reboot the board with a reboot shell command, DCAN0 CTL register is 0xE now and DCAN0 works now.

This happens every time. Does anyone have any clue about it? Or some more information is needed?

Thanks,

Wenhu

  • Hello Wenhu,

    This issue can be caused by incorrect initialization of parity RAM.

    Try to disable the Parity check functionality by DCAN_CTL[13:10] PMD bit field. Then check if your problem is available yet.

    Best regards,

    Yanko

  • Hello Yanko,

    I tried to disable Parity check by setting PMD as 0x5 and verified that it didn't make any difference.

    If c_can_chip_config() is called twice, CAN0 works for most times, about 4 in 5 cold start. When it failed to work, DCAN_CTL changed between 0x1 and 0x7, and DCAN_ES changed between 0x207 and 0x07.

    Regards,

    Wenhu

  • Hello Wenhu,

    I assume that, your problems are caused by DCAN Ram Initialization issue. There is a similar issue described in DRA7xx Errata document. Unfortunately this document is under NDA restriction and I cannot explain you more information in the external e2e forum. Please, escalate the problem to your local FAE?

    case BOSCH_D_CAN:
            priv->regs = reg_map_d_can;
            priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
            priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
            priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;

            if (pdev->dev.of_node)
                priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
            else
                priv->instance = pdev->id;

            priv->raminit_bits.start =
                (1 << (priv->instance + CAN_DEFAULT_RAMINIT_START_BIT));
            priv->raminit_bits.done =
                (1 << (priv->instance + CAN_DEFAULT_RAMINIT_DONE_BIT));

            if (CAN_FLAG_ENABLED(DRA7_DCAN1_RAMINIT_BITS, priv->flags)) {
                priv->raminit_bits.start =
                    DRA7_DCAN1_RAMINIT_BITS_START;
                priv->raminit_bits.done =
                    DRA7_DCAN1_RAMINIT_BITS_DONE;
            }
            if (CAN_FLAG_ENABLED(DRA7_DCAN2_RAMINIT_BITS, priv->flags)) {
                priv->raminit_bits.start =
                    DRA7_DCAN2_RAMINIT_BITS_START;
                priv->raminit_bits.start =
                    DRA7_DCAN2_RAMINIT_BITS_DONE;
            }

            res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
            priv->raminit_ctrlreg =    devm_ioremap_nocache(&pdev->dev,
                    res->start, resource_size(res));
            if (!priv->raminit_ctrlreg || priv->instance < 0)
                dev_info(&pdev->dev, "control memory is not used for raminit\n");
            else if (CAN_FLAG_ENABLED(DRA7_DCAN_RAMINIT, priv->flags))
                priv->raminit = c_can_hw_raminit_dra7;
            else
                priv->raminit = c_can_hw_raminit;
            break;
        default:
            ret = -EINVAL;
            goto exit_free_device;
        }

    Could you change the clock source for DCAN module by the register in PRCM?

    Switch to higher clock frequency by CM_WKUPAON_DCAN1_CLKCTRL[24] CLKSEL - 0x1 - Selects SYS_CLK2

    Best regards,

    Yanko

  • Yanko,

    Thanks. The highlighted code was already in my code. It couldn't fix my issue.

    Regards,

    Wenhu

  • Hi Wenhu,

    Would you please tell us which version of your board, mine is REV E1, DCAN doesn't work on both cold and warm reset.

    Cheers,

    Zumeng