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.

TDA4VH-Q1: TDA4VH DFU Error

Part Number: TDA4VH-Q1
Other Parts Discussed in Thread: TDA4VH

Tool/software:

I heard there is a dfu issue when using TDA4VH 9.2 SDK. Is there a way to solve this issue without upgrading the SDK version?

  • so I'm using 10.0 SDK to do DFU.

    I'm getting the following error while writing rootfs.

    What's the cause?

    DFU state(2) = dfuIDLE, status(0) = No error condition is present
    Done!
    u-boot.img.raw Success
    dfu-util 0.11-dev
    
    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2021 Tormod Volden and Stefan Schmidt
    This program is Free Software and has ABSOLUTELY NO WARRANTY
    Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
    
    dfu-util: Warning: Invalid DFU suffix signature
    dfu-util: A valid DFU suffix will be required in a future dfu-util release
    Opening DFU capable USB device...
    Device ID 0451:6168
    Device DFU version 0110
    Claiming USB DFU Interface...
    Setting Alternate Interface #1 ...
    Determining device status...
    DFU state(2) = dfuIDLE, status(0) = No error condition is present
    DFU mode device DFU version 0110
    Device returned transfer size 4096
    Copying data from PC to DFU device
    Download	[=                        ]   7%    995377152 bytesdfu-util: Error during download (LIBUSB_ERROR_IO)
    

    The dmesg log shows an error that the USB connection was lost in the middle.

  • Hi Kim 

    Which image you are trying to send ?

    Regards
    Diwakar

  • Hi Dhyani

    I found the cause

    It looks like it's a pmic watchdog issue since it reboots at 13 minutes

    Can you tell me how to disable pmic wd_en on the uboot side?

    Regards,

    Kim

  • HI Kim,

    It looks like it's a pmic watchdog issue since it reboots at 13 minutes

    Are you using custom board or TI EVM ? Do you know the reason for this reset.

    Regards
    Diwakar

  • Hi, Dhyani

    We are working on a custom board.

    The cause was a problem with the pmic nvm version.

    issue:

    https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1444589/tps6594-q1-debug-tps6594

    The kernel solved it by modifying the corresponding register value, but when updating with DFU, the value cannot be modified, so it is reset.

    Regards,

    Kim

  • Hi Kim,

    That is an I2C register write that was needed as per the above E2E post that you have shared. So at what stage do you need that to be written?

    - Keerthy

  • Hi Keerthy

    In uboot, enter the command below.

    i2c mw 0x12 0x09.1 0xbf 1

    In kernel, enter the command below.

    i2cset -f -y 2 0x12 0x09 0xbf

    We want to proceed by modifying the tps65941.c code in the uboot driver.

    Regards,

    Kim

  • Hi Kim,

    Assuming tps65941_buck_val gets called in your boot flow:

    diff --git a/drivers/power/regulator/tps65941_regulator.c b/drivers/power/regulator/tps65941_regulator.c
    index ee86b8894a..bdfdc183d8 100644
    --- a/drivers/power/regulator/tps65941_regulator.c
    +++ b/drivers/power/regulator/tps65941_regulator.c
    @@ -173,6 +173,7 @@ static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
     
            ret = pmic_reg_write(dev->parent, adr, ret);
     
    +       ret = pmic_reg_write(dev->parent, 0x9, 0xbf);
            udelay(uwait);
     
            return ret;
    

    Best Regards,
    Keerthy

  • Hi, Keerthy

    I applied the patch, but the symptoms seem to be the same.

    I tried to leave a log, but it seems like the log is not left in that part.

    Did I do something wrong?

    Regars,

    Kim

  • Kim,

    This is enabled at R5 SPL. On your custom board are you have AVS - Adaptive voltage scaling enabled?
    If that is not enabled then this function is not called.

    - Keerthy

  • Keerthy,

    The schematic for AVS is the same as the Devkit.

    Is this the correct part?

    The actual i2c address is also confirmed on uboot.

    Regards,

    Kim

  • Keerthy,

    // SPDX-License-Identifier: GPL-2.0
    /*
     * (C) Copyright 2019 Texas Instruments Incorporated, <www.ti.com>
     * Keerthy <j-keerthy@ti.com>
     */
    
    #include <common.h>
    #include <fdtdec.h>
    #include <errno.h>
    #include <dm.h>
    #include <i2c.h>
    #include <log.h>
    #include <linux/printk.h>
    #include <power/pmic.h>
    #include <power/regulator.h>
    #include <power/tps65941.h>
    #include <dm/device.h>
    
    #define TPS65941_WD_THR_CFG		0x409
    #define TPS65941_WD_EN_MASK		BIT(6)
    
    static const struct pmic_child_info pmic_children_info[] = {
    	{ .prefix = "ldo", .driver = TPS65941_LDO_DRIVER },
    	{ .prefix = "buck", .driver = TPS65941_BUCK_DRIVER },
    	{ },
    };
    
    static int tps65941_write(struct udevice *dev, uint reg, const uint8_t *buff,
    			  int len)
    {
    	if (dm_i2c_write(dev, reg, buff, len)) {
    		pr_err("write error to device: %p register: %#x!\n", dev, reg);
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int tps65941_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
    {
    	if (dm_i2c_read(dev, reg, buff, len)) {
    		pr_err("read error from device: %p register: %#x!\n", dev, reg);
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int tps65941_bind(struct udevice *dev)
    {
    	ofnode regulators_node;
    	int children;
    
    	if (dev->driver_data == TPS65941_WD)
    		return 0;
    	
    	regulators_node = dev_read_subnode(dev, "regulators");
    	if (!ofnode_valid(regulators_node)) {
    		debug("%s: %s regulators subnode not found!\n", __func__,
    		      dev->name);
    		return -ENXIO;
    	}
    
    	debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
    
    	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
    	if (!children)
    		printf("%s: %s - no child found\n", __func__, dev->name);
    
    	/* Probe all the child devices */
    	return dm_scan_fdt_dev(dev);
    }
    
    static int stop_watchdog(struct udevice *dev)
    {
    	int ret;
    	
    	/* Disable WD */
    	ret = dm_i2c_reg_read(dev, TPS65941_WD_THR_CFG);
    	if (1) {
    		pr_err("failed to read i2c reg (%d)\n", ret);
    		//return ret;
    	}
    
    	ret &= ~TPS65941_WD_EN_MASK;
    	ret = dm_i2c_reg_write(dev, TPS65941_WD_THR_CFG, ret);
    	if (1) {
    		pr_err("%s: %s write WD_EN fail!\n", __func__, dev->name);
    		//return ret;
    	}
    
    	ret = dm_i2c_reg_read(dev, TPS65941_WD_THR_CFG);
    	if (1) {
    		pr_err("failed to read back i2c reg (%d)\n", ret);
    		//return ret;
    	}
    
    	return 0;
    }
    
    static int tps65941_probe(struct udevice *dev)
    {
    	pr_err("%s: %s ------------------------!\n", __func__, dev->name);
    		
    	if (dev->driver_data == TPS65941_WD)
    		return stop_watchdog(dev);
    	return 0;
    }
    
    
    static struct dm_pmic_ops tps65941_ops = {
    	.read = tps65941_read,
    	.write = tps65941_write,
    };
    
    static const struct udevice_id tps65941_ids[] = {
    	{ .compatible = "ti,tps659411", .data = TPS659411 },
    	{ .compatible = "ti,tps659412", .data = TPS659411 },
    	{ .compatible = "ti,tps659413", .data = TPS659413 },
    	{ .compatible = "ti,lp876441",  .data =  LP876441 },
    	{ .compatible = "ti,tps65224",  .data =  TPS65224 },
    	{ .compatible = "ti,tps6594-q1", .data =  TPS659411 },
    	{ .compatible = "ti,tps6593-q1", .data =  TPS659413 },
    	{ .compatible = "ti,lp8764-q1",  .data =  LP876441 },
    	{ .compatible = "ti,tps659413_wd",  .data =  TPS65941_WD },
    	{ }
    };
    
    U_BOOT_DRIVER(pmic_tps65941) = {
    	.name = "tps65941_pmic",
    	.id = UCLASS_PMIC,
    	.of_match = tps65941_ids,
    	.bind = tps65941_bind,
    	.probe = tps65941_probe,
    	.ops = &tps65941_ops,
    };

    I'm trying to proceed by adding tps65941 entry to mcu_i2c0, but it doesn't work properly.

    It seems that 0x12 device driver is not running.

    Can't there be two drivers running?

    Regards,

    Kim

  • The schematic for AVS is the same as the Devkit.

    Is this the correct part?

    The actual i2c address is also confirmed on uboot

    So this is a standalone regulator and this does not come under TPS6594x. The slave ID is 0x48 on the EVMs not sure if its 0x12 on your custom board.
    In the PMIC probe function can you add the register write directly?

    - Keerthy

  • The pmic we use is the same as the devkit.

    So the slave id is 0x48.

    Currently 0x48 is checked in wkup_i2c and 0x12 is checked in mcu_i2c. That's why the i2c bus is different. I don't have much experience with u_boot side code. Is there a way to write to i2c bus where mcu_i2c 0x12 is?

    Regards,

    Kim

  • Hi Kim,

    All the AVS code gets executed in the R5 SPL phase. 

    Currently 0x48 is checked in wkup_i2c and 0x12

    The WKUP_I2C can be used to write to slave at 0x48? ESM PMIC driver also could be used to write to I2C.

    drivers/misc/esm_pmic.c

    pmic_esm_probe

    Check if the above function is getting called, if yes then its simple to add:

    ret = pmic_reg_write(dev->parent, 0x9, 0xBF);

    - Keerthy

  • Hi, Keerthy

    The function is called, but it still outputs only the value 0x2c at address 0x09. This is the same value as the value at address 0x09 in the nvm.bin file.

    The value I want to change is address 0x409.

    Regards,

    Kim

  • Hi Kim,

    You can try something like what is done in: board/ti/common/board_detect.c

    rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
    if (rc)
    return rc;
    rc = dm_i2c_probe(bus, dev_addr, 0, &dev);
    if (rc)
    return rc;

    bus_addr should be the MCU_I2C bus number.
    dev_addr is 0x12 for MCU_I2C i.e the slave_id.

    then you could do dm_i2c_write

    Let me know if that helps. We don't have PMIC watchdog support in the software so need to workaround something like above.

    - Keerthy

  • Hi Keerthy

    I checked the trm document because it was confirmed to be a power issue. I checked the table below.

    ti-processor-sdk-linux-adas-j784s4-evm-10_00_00_08/board-support/ti-u-boot-2024.04+git/arch/arm/mach-k3/r5/j784s4/dev-data.c

    Then, after modifying it as shown below, it seems that the 13-minute watchdog issue was resolved.

    I think I need to test it more.

    Will there be any problems with the board if I apply the above patch?

    Regards,

    Kim

  • Kim,

    That was the dependency on MCU_I2C0. What you have done is to initialize the MCU_I2C0 as the PMCI needs it. So this is correct.
    I hope now you are able to access the PMIC registers in the SPL PMIC driver.

    Best Regards,
    Keerthy