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.

Linux/AM3359: board with tps65218 pmic does not shutdown but reboots instead

Part Number: AM3359
Other Parts Discussed in Thread: TPS65218D0, TPS65218, TPS65217

Tool/software: Linux

Hi,

we upgraded a stable custom AM335x design from TPS65217D PMIC to TPS65218D0.

The boards boots fine ti linux kernel 4.14.79 from processor sdk. Rebooting via "reboot" is fine.

But shutdown via "halt -p" does not shutdown but reboot the board. I found that this - or something similiar - was an issue with prior

silicon of the PMIC. But we have the latest - chipid is 5.

Design is based on http://www.ti.com/lit/ug/slvuaa9a/slvuaa9a.pdf.

I am not sure if this hardware of software releated. I took the TPS65218 devicetree node from am437x-sk-evm.dts.

DCDC4 is used for all 3.3V peripherals on our board. Our initial TPS65217 based design was always fine.

Regards,

Matthias

  • I assume "poweroff" does the same thing?  Did you deviate in any way from the design?  For example, are you using the AM437x RTC and is the RTC_PMIC_EN pin connected to the PWR_EN pin of the PMIC?  What does your RTC node look like?

  • HI Brad,

    poweroff and "halt -p" is the same.

    Yes, the PMIC_EN is connected to PWR_EN - same as on our initial 65217 based design. We are not using DCDC5 for the AM335x because the AM335x internal LDO is used (RTC_KALDO_EN# is low). This is an artefact from our previous design.

    Of course we have the "system-power-controller" attribute in the RTC node. When I remove it the system does not reboot and does not poweroff - as expected.

    I see the message "System will go to power_off state ..." from rtc-omap.c. Then after 1-2 seconds the system restarts. In this case I see PWR_EN low for 500ms.

    So what might cause starting up again after PWR_EN went low?

    Matthias

  • Hi again,

    I add a poweroff command to our U-Boot bootloader implementation:

    static int am335x_rtc_poweroff(void)
    {
        struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
        void *base = (void *)RTC_BASE;
        int reg_val;
        struct rtc_time tm;

        /* enable 32kHz counter */
        reg_val = readl(&rtc->ctrl);
        writel(reg_val | OMAP_RTC_CTRL_STOP_RTC, &rtc->ctrl);

        /* Set the Power Enable PMIC */
        reg_val = readl(base +    OMAP_RTC_PMIC_REG);
        writel(reg_val | OMAP_RTC_PWR_EN_EN, base + OMAP_RTC_PMIC_REG);

        /* Rather than play the roll over game, just wait an extra second */
        do {
            /* Wait until the busy bit is cleared.    Max 15 uS */
            while (readl(&rtc->status) & OMAP_RTC_STATUS_BUSY_EN)
                ;

            /* Read the current time, convert from binary */
            tm.tm_sec = bcd2bin(readb(&rtc->second));
            tm.tm_min = bcd2bin(readb(&rtc->minutes));
            tm.tm_hour = bcd2bin(readb(&rtc->hours));
            tm.tm_mday = bcd2bin(readb(&rtc->day));
            tm.tm_mon = bcd2bin(readb(&rtc->month));
            tm.tm_year = bcd2bin(readb(&rtc->year));

            if (tm.tm_sec == 59)
                mdelay(100);

        } while (tm.tm_sec == 59);

        tm.tm_sec++;

        /* Write the Alarm 2 Register with the shutdown time */
        writeb(bin2bcd(tm.tm_sec), base + OMAP_RTC_ALARM2_SEC_REG);
        writeb(bin2bcd(tm.tm_min), base + OMAP_RTC_ALARM2_MIN_REG);
        writeb(bin2bcd(tm.tm_hour), base + OMAP_RTC_ALARM2_HOUR_REG);
        writeb(bin2bcd(tm.tm_mday), base + OMAP_RTC_ALARM2_DAY_REG);
        writeb(bin2bcd(tm.tm_mon), base + OMAP_RTC_ALARM2_MON_REG);
        writeb(bin2bcd(tm.tm_year), base + OMAP_RTC_ALARM2_YEAR_REG);

        /* Enable the Alarm 2 Interrupt */
        reg_val = readl(&rtc->irq);
        writel(reg_val | OMAP_RTC_INT_ALM2_EN, &rtc->irq);

        /* Power is being pulled */
        while (1)
            mdelay(1000);

        return 0;
    }


    int do_poweroff(cmd_tbl_t *cmdtp, int flag,
                    int argc, char * const argv[])
    {
        return am335x_rtc_poweroff();
    }

    I am getting the same behavior here! Then I played with the AC_DET pin. My setup supplies our board via 5V USB power. This pulls down AC_DET pin - as intended. When I remove the external 5V our board run from battery and AC_DET is pulled high. I noticed that the board goes to OFF state after calling poweroff command when AC_DET is high and reboots when AC_DET is low. From the datasheet I expected that the PMIC shuts down independant of AC_DET. Just a falling edge (!) on PB or AC_DET should to the wakeup. But here a low level on AC_DET does not allow shutdown but causes a reboot.

    This looks strange. Or did I misunderstand the AC_DET pin?

    MAtthias

  • Matthias,

    You've made a great discovery.  Thanks for following up with the details.  Given the direction this thread has taken, we really need someone from the PMIC team to comment on what's happening.  While I could move this thread to the PMIC forum, I think all the software discussion in this thread might only confuse things.  Would you mind starting a brand new thread here:

    https://e2e.ti.com/support/power-management/f/196

    You could more or less just copy and paste your last couple paragraphs.  I think that would be better.  We can keep this thread open until we get closure on the other.  There may still be some software-related discussion once we get clarification on the AC_DET functionality.

    Best regards,
    Brad