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/PROCESSOR-SDK-AM335X: Use DMTIMER with IRQ to toggle GPIO every 100ms

Part Number: PROCESSOR-SDK-AM335X


Tool/software: Linux

Platform - AM335x Starter Kit

Target - Use an accurate timer with IRQ to toggle GPIO every 100ms.(IRQ shouldn't be delayed more than a period.)

Reference - DMTIMER: e2e.ti.com/.../415079

-------------------------------------------------

Hi,

The question is, I can't request the timer pointer by using

1. omap_dm_timer_request_specific(7) -> ask me to use omap_dm_timer_request_by_cap/node, which I think is because I am using dts(?)

Note. I am using default am335x-evmsk.dts + am33xx.dtsi

2. omap_dm_timer_request_by_cap() -> gets null pointer

I want to request a specific timer and configure it to interrupt every 100ms.

I am totally new to TI platform, please guide me to reach the goal.

Thank you!

Post my work below.

static irqreturn_t timer_irq_handler(int irq, void * dev_id)
{
int status = 0;

/* Read the current Status */
status = omap_dm_timer_read_status(pTimer);

/* Clear the timer interrupt */
if (status == OMAP_TIMER_INT_MATCH)
{
omap_dm_timer_write_status(pTimer, OMAP_TIMER_INT_MATCH);
}

/* Indicate the Interrupt was handled */
return IRQ_HANDLED;
}

static int dmtimer_init(void)
{
int ret = 1;
struct clk *pTimerClk;

/* Need to request Timer 7 */
pTimer = omap_dm_timer_request_specific(7);
if(pTimer == NULL){
/* no timers available */
printk(KERN_INFO "DM timer 7 not available!!\n");
return -1;
}

/* Set the Clock source to the System Clock */
ret = omap_dm_timer_set_source(pTimer, OMAP_TIMER_SRC_SYS_CLK);

/* Determine what IRQ the timer triggers */
timerIrq = omap_dm_timer_get_irq(pTimer);

/* Setup the IRQ handler */
ret = request_irq(timerIrq, timer_irq_handler, IRQF_TIMER, "ext_wdt", NULL);

/* Setup the timer to trigger the IRQ on the match event */
omap_dm_timer_set_int_enable(pTimer, OMAP_TIMER_INT_MATCH);

/* Get the Clock rate in Hz */
pTimerClk = omap_dm_timer_get_fclk(pTimer);
timerRate = clk_get_rate(pTimerClk);

/* Enable the Timer */
/* Needs to be done before we can write to the counter */
omap_dm_timer_enable(pTimer);

/* Set the initial Count */
/* According to section 20.1.3.5 Pulse-Width Modulation, an overflow or match be used to toggle when a compare condition occurs*/
/* Therefore it we will trigger the overflow event almost immediately to ensure our toggle will be generated quickly */
omap_dm_timer_write_counter(pTimer, (0xFFFFFFFF - 5));

/* Setup the Load Register */
/* Setup as autoload to set the the counter back to 0 on an overflow */
omap_dm_timer_set_load(pTimer, 1, 0);

/* Set the the compare register to 100 ms second */
/* This will ensure the signal toggle of 100 ms after the overflow event*/
omap_dm_timer_set_match(pTimer, 1, timerRate/10);

/* Start the timer */
ret = omap_dm_timer_start(pTimer);
printk(KERN_INFO "Timer Start ret %d\n", ret);

/*
* A non 0 returns means the call to init_modules failed; module can't be loaded
*/
return 0;
}
arch_initcall(dmtimer_init)

  • Hi Howard,

    You need to use omap_dm_timer_request_by_node(), refer to the below TI drivers for reference:

    linux-kernel/drivers/net/ethernet/ti/cpts.c
    linux-kernel/drivers/pwm/pwm-omap-dmtimer.c
    linux-kernel/drivers/remoteproc/omap_remoteproc.c

    Refer also to below e2e threads:

    e2e.ti.com/.../629859
    e2e.ti.com/.../1487385
    e2e.ti.com/.../2243873

    Regards,
    Pavel
  • Hi,

    Thank you for your advice.

    I revise my code following the example in https://e2e.ti.com/support/processors/f/791/p/415079/1487385#1487385,
    using omap_dm_timer_request_by_node(), which I believe is in linux-4.14.79/drivers/clocksource/timer-ti-dm.c. ----> #include <clocksource/timer-ti-dm.h>

    However, it still returns NULL.
    It is OK to get pTimerDtsNode, but failed into "No DM timer available!!".

    After tracing code, I find out that
    list_for_each_entry(t, &omap_timer_list, node) {...} doesn't loop any member. (I add pr_warn() inside, but print out nothing.)
    Does it mean omap_timer_list is not initialized? (Or has no item?)

    BTW, I am not going to use PWM output, just want to call another function to set/reset GPIO.
    Does it mean that I don't need to configure PWM such as calling omap_dm_timer_set_pwm()?

    Below is my revised code. But I think the root cause of current issue might be in other places.

    ext_wdt {
    	compatible = "cust_ext_wdt";
    	status = "okay";
    	DMtimer = <&timer7>;
    };
    static int initExtWdt(struct platform_device *pdev)
    {
        int ret = 1;
        struct clk *pTimerClk;  
        struct device_node *pTimerDtsNode = NULL;
    
        /* Attempt to request a timer based on the device node */
        pTimerDtsNode = of_parse_phandle(pdev->dev.of_node, "DMtimer", 0);    
        if (NULL == pTimerDtsNode) {
            printk(KERN_INFO "of_parse_phandle() failed!!\n");
            return -1;
        }
        else if(NULL == (pTimer = omap_dm_timer_request_by_node(pTimerDtsNode))){
            /* no timers available */
            printk(KERN_INFO "No DM timer available!!\n");
            return -1;
        }
    
        /* Set the Clock source to the System Clock */
        ret = omap_dm_timer_set_source(pTimer, OMAP_TIMER_SRC_SYS_CLK);
    
        /* Determine what IRQ the timer triggers */
        timerIrq = omap_dm_timer_get_irq(pTimer);
    
        /* Setup the IRQ handler */
        ret = request_irq(timerIrq, timerIrqHandler, IRQF_TIMER, "ext_wdt", NULL);
    
        /* Setup the timer to trigger the IRQ on the match event */
        omap_dm_timer_set_int_enable(pTimer, OMAP_TIMER_INT_MATCH);
        
        /* Get the Clock rate in Hz */
        pTimerClk = omap_dm_timer_get_fclk(pTimer);
        timerRate = clk_get_rate(pTimerClk);
    
        /* Enable the Timer */
        /* Needs to be done before we can write to the counter */
        omap_dm_timer_enable(pTimer);
    
        /* Set the initial Count */
        /* According to section 20.1.3.5 Pulse-Width Modulation, an overflow or match be used to toggle when a compare condition occurs*/
        /* Therefore it we will trigger the overflow event almost immediately to ensure our toggle will be generated quickly */
        omap_dm_timer_write_counter(pTimer, (0xFFFFFFFF - 5));
    
        /* Setup the Load Register */
        /* Setup as autoload to set the the counter back to 0 on an overflow */
        omap_dm_timer_set_load(pTimer, 1, 0);
    
        /* Set the the compare register to 100 ms second */
        /* This will ensure the signal toggle of 100 ms after the overflow event*/
        omap_dm_timer_set_match(pTimer, 1, timerRate/10);
    
        /* Start the timer */
        ret = omap_dm_timer_start(pTimer);
        printk(KERN_INFO "Timer Start ret %d\n", ret);
    
        /* 
        * A non 0 returns means the call to init_modules failed; module can't be loaded
        */
        return 0;
    }
    
    static const struct of_device_id extWdtOfMatch[] = {
        { .compatible   = "cust_ext_wdt" },
        {},
    };
    
    ...
    
    static struct platform_driver extWdtDriver = {
        .driver = {
            .name   = DRIVER_NAME,
            .owner  = THIS_MODULE,
            .of_match_table = extWdtOfMatch,
        },
        .probe  = initExtWdt,
        .remove = exitExtWdt,
    };
    
    module_platform_driver(extWdtDriver);

  • Howard,

    If you are not planning to use PWM feature of timers, then no need to use omap_dm_timer_set_pwm(). You need to align to below example:

    e2e.ti.com/.../1487385

    Make sure when you update your DTS file, you are also rebuilding it, create new dtb and load this new dtb.

    Check also for any warnings during building your kernel. dtb and modules.

    Another things you can try:

    - add to your code "static struct omap_dm_timer *pTimer = NULL;"
    - check if timer7 is enabled in devcie PRCM
    - check if setting pinmux of timer7 will solve the issue
    - check if requesting another timer (not timer7) will work
    - check if enable timer7 in DTS will solve the issue

    &timer7 {

    pinctrl-names = "default";

    pinctrl-0 = <&timer7_pins_default>;

    status = "okay";

    }


    Regards,
    Pavel
  • Hi Pavel,

    Many thanks for your help.

    For your suggestions,

    - add to your code "static struct omap_dm_timer *pTimer = NULL;"
    > Already added. Just didn't post here.


    - check if timer7 is enabled in devcie PRCM
    > Could you teach me how to do this?


    - check if setting pinmux of timer7 will solve the issue
    > The am335x-evmsk.dts don't have timer configurations, does it mean Starter Kit don't support this feature?


    - check if requesting another timer (not timer7) will work
    > I'll try.


    - check if enable timer7 in DTS will solve the issue
    > As the 3rd point. Yes, I didn't enable timer7. (default dts don't configure any timer.)
    So I have to add &timer7 {...) as you said.
    However, which pin should be in timer7_pins_default? (I'm using am335x Starter Kit)

    Thanks!

  • Howard,

    howard shih said:
    - check if timer7 is enabled in devcie PRCM
    > Could you teach me how to do this?

    You can print CM_PER_TIMER7_CLKCTRL register just before request the timer, and check if the value is correct or not.

    Refer to the below e2e thread for details:

    howard shih said:
    - check if setting pinmux of timer7 will solve the issue
    > The am335x-evmsk.dts don't have timer configurations, does it mean Starter Kit don't support this feature?

    Yes, but you can add timer7 pinmux by yourself

    howard shih said:
    However, which pin should be in timer7_pins_default? (I'm using am335x Starter Kit)

    You can overwrite SW1 button pinmux:

    gpio_keys_s0: gpio_keys_s0 {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE7)    /* gpmc_oen_ren.gpio2_3 */

    You can change pin T7 usage from gpio2_3 (SW1 button) (mode 7) to timer7 (mode 2).

    Regards,
    Pavel

  • Hi Pavel,

    OKay, I add pinmux and enable timer in dts.

    timer7_pins: timer7_pins_default {
    pinctrl-single,pins = <
    AM33XX_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_oen_ren.gpio2_3 */
    >;
    };

    &timer7 {
    pinctrl-names = "default";
    pinctrl-0 = <&timer7_pins>;
    status = "okay";
    };

    and I use devmem2 to read timer7 register 0x4804a000, however, it fails.
    Only timer1 and timer2 are accessable. (the address is refer to am33xx.dtsi.)

    read timer7 fail.
    ~ # devmem2 0x4804a000
    /dev/mem opened.[ 89.482790] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6fda000
    [ 89.491196] pgd = c70b8000
    [ 89.493929] [b6fda000] *pgd=868fd831, *pte=4804a303, *ppte=4804aa33

    Target Memory(0x4804A000) mapped at address 0xb6fda000.
    Bus error

    read timer2 OK.
    ~ # devmem2 0x48040000
    /dev/mem opened.
    Target Memory(0x48040000) mapped at address 0xb6f60000.
    Value at address 0x48040000 (0xb6f60000): 0x4FFF1301

    But, I change my dts to use timer2, it still loops nothing, and return null pTimer.

    My understanding is am335x-evmsk.dts doesn't have any configurations about timer1 and timer2.
    So I don't know why timer1 and timer2 are enabled by default. ---> I think timers are not configured by dts.
    If am33xx.dtsi is all we need to enable timer, timer1~7 should all be enabled because their codes are the same.

    Is my understanding correct?
    Thank you!
  • Howard,

    Timer2 is enabled in u-boot (in below files) and stays enabled in kernel and userspace.

    u-boot-2018.01/arch/arm/dts/am335x-evmsk.dts
    u-boot-2018.01/arch/arm/mach-omap2/am33xx/clock_am33xx.c

    You can not use Timer2, as this timer is used the kernel.

    Usually a module (i.e. timer7) should be enabled in kernel DTS file through "status = okay" entry. Can you please attach your kernel DTS file for review?

    You can also try below things as workaround to kernel DTS timer7 enable procedure:

    1. enable timer7 in u-boot, similar to timer2

    2. enable timer7 in linux kernel through writing to CM_PER_TIMER7_CLKCTRL register. You can use function am33xx_cm_write_reg(), which is using writel_relaxed(), or directly use writel_relaxed or use __raw_writel(). Refer to below kernel files for reference:

    linux-4.14.79/arch/arm/mach-omap2/cm33xx.c
    linux-4.14.79/drivers/clk/ti/adpll.c
    linux-4.14.79/sound/soc/davinci/davinci-mcasp.c

    3. Enable timer7_fck through the clock framework

    linux-4.14.79/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
    linux-4.14.79/drivers/clk/ti/clk-33xx.c

    processors.wiki.ti.com/.../Clock_Framework_User_Guide

    Regards,
    Pavel
  • Hi,

    Attach dts code here.

    /*
     * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as
     * published by the Free Software Foundation.
     */
    
    /*
     * AM335x Starter Kit
     * www.ti.com/.../tmdssk3358
     */
    
    /dts-v1/;
    
    #include "am33xx.dtsi"
    #include <dt-bindings/pwm/pwm.h>
    #include <dt-bindings/interrupt-controller/irq.h>
    
    / {
    	model = "TI AM335x EVM-SK";
    	compatible = "ti,am335x-evmsk", "ti,am33xx";
    
    	cpus {
    		cpu@0 {
    			cpu0-supply = <&vdd1_reg>;
    		};
    	};
    
    	memory@80000000 {
    		device_type = "memory";
    		reg = <0x80000000 0x10000000>; /* 256 MB */
    	};
    
    	chosen {
    		stdout-path = &uart0;
    	};
    
    	vbat: fixedregulator0 {
    		compatible = "regulator-fixed";
    		regulator-name = "vbat";
    		regulator-min-microvolt = <5000000>;
    		regulator-max-microvolt = <5000000>;
    		regulator-boot-on;
    	};
    
    	lis3_reg: fixedregulator1 {
    		compatible = "regulator-fixed";
    		regulator-name = "lis3_reg";
    		regulator-boot-on;
    	};
    
    	wl12xx_vmmc: fixedregulator2 {
    		pinctrl-names = "default";
    		pinctrl-0 = <&wl12xx_gpio>;
    		compatible = "regulator-fixed";
    		regulator-name = "vwl1271";
    		regulator-min-microvolt = <1800000>;
    		regulator-max-microvolt = <1800000>;
    		gpio = <&gpio1 29 0>;
    		startup-delay-us = <70000>;
    		enable-active-high;
    	};
    
    	vtt_fixed: fixedregulator3 {
    		compatible = "regulator-fixed";
    		regulator-name = "vtt";
    		regulator-min-microvolt = <1500000>;
    		regulator-max-microvolt = <1500000>;
    		gpio = <&gpio0 7 GPIO_ACTIVE_HIGH>;
    		regulator-always-on;
    		regulator-boot-on;
    		enable-active-high;
    	};
    
    	ext_wdt {
    		compatible = "cust_ext_wdt";
    		status = "okay";
    		DMtimer = <&timer4>;
    	};
    
    	leds {
    		pinctrl-names = "default";
    		pinctrl-0 = <&user_leds_s0>;
    
    		compatible = "gpio-leds";
    
    		/*led1 {
    			label = "evmsk:green:usr0";
    			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
    			default-state = "off";
    		};
    
    		led2 {
    			label = "evmsk:green:usr1";
    			gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
    			default-state = "off";
    		};*/
    
    		led3 {
    			label = "evmsk:green:mmc0";
    			gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
    			linux,default-trigger = "mmc0";
    			default-state = "off";
    		};
    
    		led4 {
    			label = "evmsk:green:heartbeat";
    			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
    			linux,default-trigger = "heartbeat";
    			default-state = "off";
    		};
    	};
    
    	gpio_buttons: gpio_buttons0 {
    		compatible = "gpio-keys";
    		#address-cells = <1>;
    		#size-cells = <0>;
    
    		switch1 {
    			label = "button0";
    			linux,code = <0x100>;
    			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
    		};
    
    		switch2 {
    			label = "button1";
    			linux,code = <0x101>;
    			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
    		};
    
    		switch3 {
    			label = "button2";
    			linux,code = <0x102>;
    			gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
    			wakeup-source;
    		};
    
    		switch4 {
    			label = "button3";
    			linux,code = <0x103>;
    			gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
    		};
    	};
    
    	lcd_bl: backlight {
    		compatible = "pwm-backlight";
    		pwms = <&ecap2 0 50000 PWM_POLARITY_INVERTED>;
    		brightness-levels = <0 58 61 66 75 90 125 170 255>;
    		default-brightness-level = <8>;
    	};
    
    	sound {
    		compatible = "simple-audio-card";
    		simple-audio-card,name = "AM335x-EVMSK";
    		simple-audio-card,widgets =
    			"Headphone", "Headphone Jack";
    		simple-audio-card,routing =
    			"Headphone Jack",	"HPLOUT",
    			"Headphone Jack",	"HPROUT";
    		simple-audio-card,format = "dsp_b";
    		simple-audio-card,bitclock-master = <&sound_master>;
    		simple-audio-card,frame-master = <&sound_master>;
    		simple-audio-card,bitclock-inversion;
    
    		simple-audio-card,cpu {
    			sound-dai = <&mcasp1>;
    		};
    
    		sound_master: simple-audio-card,codec {
    			sound-dai = <&tlv320aic3106>;
    			system-clock-frequency = <24000000>;
    		};
    	};
    
    	panel {
    		compatible = "ti,tilcdc,panel";
    		pinctrl-names = "default", "sleep";
    		pinctrl-0 = <&lcd_pins_default>;
    		pinctrl-1 = <&lcd_pins_sleep>;
    		backlight = <&lcd_bl>;
    		status = "okay";
    		panel-info {
    			ac-bias		= <255>;
    			ac-bias-intrpt	= <0>;
    			dma-burst-sz	= <16>;
    			bpp		= <32>;
    			fdd		= <0x80>;
    			sync-edge	= <0>;
    			sync-ctrl	= <1>;
    			raster-order	= <0>;
    			fifo-th		= <0>;
    		};
    		display-timings {
    			480x272 {
    				hactive		= <480>;
    				vactive		= <272>;
    				hback-porch	= <43>;
    				hfront-porch	= <8>;
    				hsync-len	= <4>;
    				vback-porch	= <12>;
    				vfront-porch	= <4>;
    				vsync-len	= <10>;
    				clock-frequency = <9000000>;
    				hsync-active	= <0>;
    				vsync-active	= <0>;
    			};
    		};
    	};
    };
    
    &am33xx_pinmux {
    	pinctrl-names = "default";
    	pinctrl-0 = <&gpio_keys_s0 &clkout2_pin &ddr3_vtt_toggle>;
    
    	ddr3_vtt_toggle: ddr3_vtt_toggle {
    		pinctrl-single,pins = <
    			0x164 (PIN_OUTPUT | MUX_MODE7)	/* ecap0_in_pwm0_out.gpio0_7 */
    		>;
    	};
    
    	lcd_pins_default: lcd_pins_default {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad8.lcd_data23 */
    			AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad9.lcd_data22 */
    			AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad10.lcd_data21 */
    			AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad11.lcd_data20 */
    			AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad12.lcd_data19 */
    			AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad13.lcd_data18 */
    			AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad14.lcd_data17 */
    			AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)	/* gpmc_ad15.lcd_data16 */
    			AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)	/* lcd_data0.lcd_data0 */
    			AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)	/* lcd_data1.lcd_data1 */
    			AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)	/* lcd_data2.lcd_data2 */
    			AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)	/* lcd_data3.lcd_data3 */
    			AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)	/* lcd_data4.lcd_data4 */
    			AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)	/* lcd_data5.lcd_data5 */
    			AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)	/* lcd_data6.lcd_data6 */
    			AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)	/* lcd_data7.lcd_data7 */
    			AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)	/* lcd_data8.lcd_data8 */
    			AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)	/* lcd_data9.lcd_data9 */
    			AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)	/* lcd_data10.lcd_data10 */
    			AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)	/* lcd_data11.lcd_data11 */
    			AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)	/* lcd_data12.lcd_data12 */
    			AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)	/* lcd_data13.lcd_data13 */
    			AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)	/* lcd_data14.lcd_data14 */
    			AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)	/* lcd_data15.lcd_data15 */
    			AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)	/* lcd_vsync.lcd_vsync */
    			AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)	/* lcd_hsync.lcd_hsync */
    			AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)	/* lcd_pclk.lcd_pclk */
    			AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)	/* lcd_ac_bias_en.lcd_ac_bias_en */
    		>;
    	};
    
    	lcd_pins_sleep: lcd_pins_sleep {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x820, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad8.lcd_data23 */
    			AM33XX_IOPAD(0x824, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad9.lcd_data22 */
    			AM33XX_IOPAD(0x828, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad10.lcd_data21 */
    			AM33XX_IOPAD(0x82c, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad11.lcd_data20 */
    			AM33XX_IOPAD(0x830, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad12.lcd_data19 */
    			AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad13.lcd_data18 */
    			AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad14.lcd_data17 */
    			AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad15.lcd_data16 */
    			AM33XX_IOPAD(0x8a0, PULL_DISABLE | MUX_MODE7)	/* lcd_data0.lcd_data0 */
    			AM33XX_IOPAD(0x8a4, PULL_DISABLE | MUX_MODE7)	/* lcd_data1.lcd_data1 */
    			AM33XX_IOPAD(0x8a8, PULL_DISABLE | MUX_MODE7)	/* lcd_data2.lcd_data2 */
    			AM33XX_IOPAD(0x8ac, PULL_DISABLE | MUX_MODE7)	/* lcd_data3.lcd_data3 */
    			AM33XX_IOPAD(0x8b0, PULL_DISABLE | MUX_MODE7)	/* lcd_data4.lcd_data4 */
    			AM33XX_IOPAD(0x8b4, PULL_DISABLE | MUX_MODE7)	/* lcd_data5.lcd_data5 */
    			AM33XX_IOPAD(0x8b8, PULL_DISABLE | MUX_MODE7)	/* lcd_data6.lcd_data6 */
    			AM33XX_IOPAD(0x8bc, PULL_DISABLE | MUX_MODE7)	/* lcd_data7.lcd_data7 */
    			AM33XX_IOPAD(0x8c0, PULL_DISABLE | MUX_MODE7)	/* lcd_data8.lcd_data8 */
    			AM33XX_IOPAD(0x8c4, PULL_DISABLE | MUX_MODE7)	/* lcd_data9.lcd_data9 */
    			AM33XX_IOPAD(0x8c8, PULL_DISABLE | MUX_MODE7)	/* lcd_data10.lcd_data10 */
    			AM33XX_IOPAD(0x8cc, PULL_DISABLE | MUX_MODE7)	/* lcd_data11.lcd_data11 */
    			AM33XX_IOPAD(0x8d0, PULL_DISABLE | MUX_MODE7)	/* lcd_data12.lcd_data12 */
    			AM33XX_IOPAD(0x8d4, PULL_DISABLE | MUX_MODE7)	/* lcd_data13.lcd_data13 */
    			AM33XX_IOPAD(0x8d8, PULL_DISABLE | MUX_MODE7)	/* lcd_data14.lcd_data14 */
    			AM33XX_IOPAD(0x8dc, PULL_DISABLE | MUX_MODE7)	/* lcd_data15.lcd_data15 */
    			AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* lcd_vsync.lcd_vsync */
    			AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* lcd_hsync.lcd_hsync */
    			AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* lcd_pclk.lcd_pclk */
    			AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* lcd_ac_bias_en.lcd_ac_bias_en */
    		>;
    	};
    
    	user_leds_s0: user_leds_s0 {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x810, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad4.gpio1_4 */
    			AM33XX_IOPAD(0x814, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad5.gpio1_5 */  
    			AM33XX_IOPAD(0x818, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad6.gpio1_6 */
    			AM33XX_IOPAD(0x81c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad7.gpio1_7 */
    			AM33XX_IOPAD(0x958, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* (B16) spi0_d1.gpio0[4] */
    			AM33XX_IOPAD(0x95c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* (A16) spi0_cs0.gpio0[5] */
    		>;
    	};
    
    	gpio_keys_s0: gpio_keys_s0 {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_advn_ale.gpio2_2 */
    			AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_wait0.gpio0_30 */
    			AM33XX_IOPAD(0x89c, PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ben0_cle.gpio2_5 */
    		>;
    	};
    
    	i2c0_pins: pinmux_i2c0_pins {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
    			AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
    		>;
    	};
    
    	uart0_pins: pinmux_uart0_pins {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
    			AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
    		>;
    	};
    
    	clkout2_pin: pinmux_clkout2_pin {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* xdma_event_intr1.clkout2 */
    		>;
    	};
    
    	ecap2_pins: backlight_pins {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x99c, MUX_MODE4)	/* mcasp0_ahclkr.ecap2_in_pwm2_out */
    		>;
    	};
    
    	cpsw_default: cpsw_default {
    		pinctrl-single,pins = <
    			/* Slave 1 */
    			AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txen.rgmii1_tctl */
    			AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxdv.rgmii1_rctl */
    			AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd3.rgmii1_td3 */
    			AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd2.rgmii1_td2 */
    			AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd1.rgmii1_td1 */
    			AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd0.rgmii1_td0 */
    			AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txclk.rgmii1_tclk */
    			AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxclk.rgmii1_rclk */
    			AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd3.rgmii1_rd3 */
    			AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd2.rgmii1_rd2 */
    			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd1.rgmii1_rd1 */
    			AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd0.rgmii1_rd0 */
    
    			/* Slave 2 */
    			AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a0.rgmii2_tctl */
    			AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a1.rgmii2_rctl */
    			AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a2.rgmii2_td3 */
    			AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a3.rgmii2_td2 */
    			AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a4.rgmii2_td1 */
    			AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a5.rgmii2_td0 */
    			AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a6.rgmii2_tclk */
    			AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a7.rgmii2_rclk */
    			AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a8.rgmii2_rd3 */
    			AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a9.rgmii2_rd2 */
    			AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a10.rgmii2_rd1 */
    			AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a11.rgmii2_rd0 */
    		>;
    	};
    
    	cpsw_sleep: cpsw_sleep {
    		pinctrl-single,pins = <
    			/* Slave 1 reset value */
    			AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
    
    			/* Slave 2 reset value*/
    			AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    		>;
    	};
    
    	davinci_mdio_default: davinci_mdio_default {
    		pinctrl-single,pins = <
    			/* MDIO */
    			AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
    			AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
    		>;
    	};
    
    	davinci_mdio_sleep: davinci_mdio_sleep {
    		pinctrl-single,pins = <
    			/* MDIO reset value */
    			AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    		>;
    	};
    
    	mmc1_pins: pinmux_mmc1_pins {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) 		/* spi0_cs1.gpio0_6 */
    			AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat0.mmc0_dat0 */
    			AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat1.mmc0_dat1 */
    			AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat2.mmc0_dat2 */
    			AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat3.mmc0_dat3 */
    			AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_cmd.mmc0_cmd */
    			AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_clk.mmc0_clk */
    			AM33XX_IOPAD(0x9a0, PIN_INPUT | MUX_MODE4)		/* mcasp0_aclkr.mmc0_sdwp */
    		>;
    	};
    
    	mcasp1_pins: mcasp1_pins {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
    			AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
    			AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
    			AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
    		>;
    	};
    
    	mcasp1_pins_sleep: mcasp1_pins_sleep {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
    			AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
    		>;
    	};
    
    	mmc2_pins: pinmux_mmc2_pins {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
    			AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
    			AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
    			AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
    			AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
    			AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
    			AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
    		>;
    	};
    
    	wl12xx_gpio: pinmux_wl12xx_gpio {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
    		>;
    	};
    
    	timer4_pins: timer4_pins_default {
    		pinctrl-single,pins = <
    			AM33XX_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_oen_ren.gpio2_3 */
    		>;
    	};
    };
    
    &timer4 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&timer4_pins>;
    	status = "okay";
    };
    
    &uart0 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&uart0_pins>;
    
    	status = "okay";
    };
    
    &i2c0 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&i2c0_pins>;
    
    	status = "okay";
    	clock-frequency = <400000>;
    
    	tps: tps@2d {
    		reg = <0x2d>;
    	};
    
    	lis331dlh: lis331dlh@18 {
    		compatible = "st,lis331dlh", "st,lis3lv02d";
    		reg = <0x18>;
    		Vdd-supply = <&lis3_reg>;
    		Vdd_IO-supply = <&lis3_reg>;
    
    		st,click-single-x;
    		st,click-single-y;
    		st,click-single-z;
    		st,click-thresh-x = <10>;
    		st,click-thresh-y = <10>;
    		st,click-thresh-z = <10>;
    		st,irq1-click;
    		st,irq2-click;
    		st,wakeup-x-lo;
    		st,wakeup-x-hi;
    		st,wakeup-y-lo;
    		st,wakeup-y-hi;
    		st,wakeup-z-lo;
    		st,wakeup-z-hi;
    		st,min-limit-x = <120>;
    		st,min-limit-y = <120>;
    		st,min-limit-z = <140>;
    		st,max-limit-x = <550>;
    		st,max-limit-y = <550>;
    		st,max-limit-z = <750>;
    	};
    
    	tlv320aic3106: tlv320aic3106@1b {
    		#sound-dai-cells = <0>;
    		compatible = "ti,tlv320aic3106";
    		reg = <0x1b>;
    		status = "okay";
    
    		/* Regulators */
    		AVDD-supply = <&vaux2_reg>;
    		IOVDD-supply = <&vaux2_reg>;
    		DRVDD-supply = <&vaux2_reg>;
    		DVDD-supply = <&vbat>;
    	};
    };
    
    &usb {
    	status = "okay";
    };
    
    &usb_ctrl_mod {
    	status = "okay";
    };
    
    &usb0_phy {
    	status = "okay";
    };
    
    &usb1_phy {
    	status = "okay";
    };
    
    &usb0 {
    	status = "okay";
    };
    
    &usb1 {
    	status = "okay";
    	dr_mode = "host";
    };
    
    &cppi41dma  {
    	status = "okay";
    };
    
    &epwmss2 {
    	status = "okay";
    
    	ecap2: ecap@48304100 {
    		status = "okay";
    		pinctrl-names = "default";
    		pinctrl-0 = <&ecap2_pins>;
    	};
    };
    
    &wkup_m3_ipc {
    	ti,needs-vtt-toggle;
    	ti,vtt-gpio-pin = <7>;
    	ti,scale-data-fw = "am335x-evm-scale-data.bin";
    };
    
    #include "tps65910.dtsi"
    
    &tps {
    	vcc1-supply = <&vbat>;
    	vcc2-supply = <&vbat>;
    	vcc3-supply = <&vbat>;
    	vcc4-supply = <&vbat>;
    	vcc5-supply = <&vbat>;
    	vcc6-supply = <&vbat>;
    	vcc7-supply = <&vbat>;
    	vccio-supply = <&vbat>;
    
    	regulators {
    		vrtc_reg: regulator@0 {
    			regulator-always-on;
    		};
    
    		vio_reg: regulator@1 {
    			regulator-always-on;
    		};
    
    		vdd1_reg: regulator@2 {
    			/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
    			regulator-name = "vdd_mpu";
    			regulator-min-microvolt = <912500>;
    			regulator-max-microvolt = <1351500>;
    			regulator-boot-on;
    			regulator-always-on;
    		};
    
    		vdd2_reg: regulator@3 {
    			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
    			regulator-name = "vdd_core";
    			regulator-min-microvolt = <912500>;
    			regulator-max-microvolt = <1150000>;
    			regulator-boot-on;
    			regulator-always-on;
    		};
    
    		vdd3_reg: regulator@4 {
    			regulator-always-on;
    		};
    
    		vdig1_reg: regulator@5 {
    			regulator-always-on;
    		};
    
    		vdig2_reg: regulator@6 {
    			regulator-always-on;
    		};
    
    		vpll_reg: regulator@7 {
    			regulator-always-on;
    		};
    
    		vdac_reg: regulator@8 {
    			regulator-always-on;
    		};
    
    		vaux1_reg: regulator@9 {
    			regulator-always-on;
    		};
    
    		vaux2_reg: regulator@10 {
    			regulator-always-on;
    		};
    
    		vaux33_reg: regulator@11 {
    			regulator-always-on;
    		};
    
    		vmmc_reg: regulator@12 {
    			regulator-min-microvolt = <1800000>;
    			regulator-max-microvolt = <3300000>;
    			regulator-always-on;
    		};
    	};
    };
    
    &mac {
    	pinctrl-names = "default", "sleep";
    	pinctrl-0 = <&cpsw_default>;
    	pinctrl-1 = <&cpsw_sleep>;
    	dual_emac = <1>;
    	status = "okay";
    };
    
    &davinci_mdio {
    	pinctrl-names = "default", "sleep";
    	pinctrl-0 = <&davinci_mdio_default>;
    	pinctrl-1 = <&davinci_mdio_sleep>;
    	status = "okay";
    };
    
    &cpsw_emac0 {
    	phy_id = <&davinci_mdio>, <0>;
    	phy-mode = "rgmii-txid";
    	dual_emac_res_vlan = <1>;
    };
    
    &cpsw_emac1 {
    	phy_id = <&davinci_mdio>, <1>;
    	phy-mode = "rgmii-txid";
    	dual_emac_res_vlan = <2>;
    };
    
    &mmc1 {
    	status = "okay";
    	vmmc-supply = <&vmmc_reg>;
    	bus-width = <4>;
    	pinctrl-names = "default";
    	pinctrl-0 = <&mmc1_pins>;
    	cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
    };
    
    &sham {
    	status = "okay";
    };
    
    &aes {
    	status = "okay";
    };
    
    &gpio0 {
    	ti,no-reset-on-init;
    };
    
    &mmc2 {
    	status = "okay";
    	vmmc-supply = <&wl12xx_vmmc>;
    	ti,non-removable;
    	bus-width = <4>;
    	cap-power-off-card;
    	keep-power-in-suspend;
    	pinctrl-names = "default";
    	pinctrl-0 = <&mmc2_pins>;
    
    	#address-cells = <1>;
    	#size-cells = <0>;
    	wlcore: wlcore@2 {
    		compatible = "ti,wl1271";
    		reg = <2>;
    		interrupt-parent = <&gpio0>;
    		interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */
    		ref-clock-frequency = <38400000>;
    	};
    };
    
    &mcasp1 {
    	#sound-dai-cells = <0>;
    	pinctrl-names = "default", "sleep";
    	pinctrl-0 = <&mcasp1_pins>;
    	pinctrl-1 = <&mcasp1_pins_sleep>;
    
    	status = "okay";
    
    	op-mode = <0>;          /* MCASP_IIS_MODE */
    	tdm-slots = <2>;
    	/* 4 serializers */
    	serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
    		0 0 1 2
    	>;
    	tx-num-evt = <32>;
    	rx-num-evt = <32>;
    };
    
    &tscadc {
    	status = "okay";
    	tsc {
    		ti,wires = <4>;
    		ti,x-plate-resistance = <200>;
    		ti,coordinate-readouts = <5>;
    		ti,wire-config = <0x00 0x11 0x22 0x33>;
    	};
    };
    
    &lcdc {
    	status = "okay";
    
    	blue-and-red-wiring = "crossed";
    };
    
    &sgx {
    	status = "okay";
    };
    
    &rtc {
    	clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
    	clock-names = "ext-clk", "int-clk";
    };
    
    &pruss_soc_bus {
    	status = "okay";
    
    	pruss: pruss@0 {
    		status = "okay";
    	};
    };

    I've also tried timer4, still the same.

    I'll try the 1~3 ways you suggested.

    Another question, if I use hrtimer to do the same thing, will the interrupt callbacks be delayed due to system busy?

    If not, probably I can use hrtimer instead.

    Howard

  • howard shih said:
    timer4_pins: timer4_pins_default { pinctrl-single,pins = < AM33XX_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_oen_ren.gpio2_3 */ >;

    This pinmux is for timer7, not timer4. For timer4 pinmux you need to have:

    - AM33XX_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE7)    /* gpmc_advn_ale.gpio2_2 */

    + AM33XX_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE2)    /* gpmc_advn_ale.timer4 */

    howard shih said:
    Another question, if I use hrtimer to do the same thing, will the interrupt callbacks be delayed due to system busy?

    hrtimers use DM_Timers. You can see some of this relationship with cat /proc/timer_list.

    Check below e2e threads:

    Regards,
    Pavel