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.

Lower down the power consumption of calixto boards

Other Parts Discussed in Thread: AM1808

Hello All,


                 i am new to EVM board handling, get struck into a problem and my platform is embedded linux. I am using calixto board with TI’s SitaraTM AM1808 and IntegraTM OMAPL-138 processor  with kernel 2.6.33 on it. I want to know how to lower down the power consumption of board but not by from hardware side, so i need a help where are changes needed  to be done  either from kernel configuration or from device drivers or any other source code in kernel. I have a application on calixto board. so any thing which i can handle from user space, it is possible to put processor into sleep mode when application is in idle mode. 

  I have tried  making changes in :-

1) /proc/sys/vm/dirty_ratio       

2) /sys/devices/system/cpu/cpuidle/current_governor_ro

3) /sys/power/state

4) /proc/sys/vm/laptop_mode

  • Hi,

    You need to enable power management support (CPU idle,CPU freq,DVFS and smart reflex if supports) in linux menuconfig option under "power management options" and CPU power management.

    Use "cat /sys/power/state" to check what are all the power management support has been enabled for the booted kernel.

    Ex:
    1) standby (suspend mode)
    2) mem (suspend to RAM)
    3) disk (suspend to disk)

    echo "mem" > /sys/power/state --> To enable "suspend to RAM" power management.

    Note:
    Pass "no_console_suspend" in bootargs to avoid serial console suspend.

    Refer the below TI wikis for Power management support.

    http://processors.wiki.ti.com/index.php/OMAP-L1_Linux_Drivers_Usage#Power_Management

    http://processors.wiki.ti.com/index.php/OMAP-L138_Power_Consumption_Summary#Activity-Based_Models

    http://processors.wiki.ti.com/index.php/Power_Module_for_C6748_and_OMAP-L138

    http://processors.wiki.ti.com/index.php/DaVinci_PSP_03.21.00.04_Device_Driver_Features_and_Performance_Guide#Device_Driver_List

  • Hi,


             I tried followings things

    1)  /sys/power/state   -----> it only  supports mem and disk    option only.

    2) Default CPUFreq governor (ornadem)  --->  in cpu freq scaling,     i tried idle,ornadend,conservative options

    but i don't find no effect in power consumption

    But in 4th link i found this but didn't how to achieve this sleep mode either from application or device driver to put my cpu into  sleep mode when app is in idle.


    Sleep Modes - You can dynamically activate CPU and device sleep modes to save power during inactivity.

    guide me

  • Hi,

    Have you tried to enable PM mode through this commands ?

    If yes, Are are you facing any issue while running those commands?

    "echo "mem" > /sys/power/state"

    "echo "disk" > /sys/power/state"

    Setting the 96MHz frequency from user space.

    target$ echo 96000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

    http://processors.wiki.ti.com/index.php/OMAP-L1_Linux_Drivers_Usage#Power_Management

    2) Default CPUFreq governor (ornadem)  --->  in cpu freq scaling,     i tried idle,ornadend,conservative options


    This is a default CPU governors but you can modify the governors from userspace

    itself through the following command

     

    target$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors 
    ---> To check avail governors or supported by kernel.

    target$ echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor   
    ---> To set "performance" governor


    Useful Power management links to understand about basics of PM

    http://processors.wiki.ti.com/index.php/AM335x_Linux_Power_Management_User_Guide
    http://processors.wiki.ti.com/index.php/AM335x_Power_Management_Standby_User%27s_Guide
    http://processors.wiki.ti.com/index.php/AM335x_Power_Management_User_Guide
    http://processors.wiki.ti.com/index.php/Sitara_Linux_Training:_Power_Management

    Note:
    Please refer your device manual & data sheet to check supported types of
    power management by your device.
  • hi,

          I got this message when type a below command and it is not taking any i/p from any where, i am using gpio to take i/p from user it got freezed. I want to know how to unfreezed it, i am using gpio as i/p. so i want that when i press gpio key it wake up my app.

    sync

    echo "mem" > /sys/power/state

    PM: Syncing filesystems ... done.
    Freezing user space processes ... (elapsed 0.01 seconds) done.
    Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
    Suspending console(s) (use no_console_suspend to debug)

    rtcwake -d /dev/rtc0 -s 20 -m mem

    I am have a viop application on my board so when i run above command it got freezed up and after 20 sec my app starts running again but creates problem for my alsa  gives error like  this                                       ------->                         alsa_dev.c  ca_thread_func: error reading data!  

    and also didn't find directory called cpufreq in the following path and its subdirectories and files how to make it visible in userspace to make changes

    /sys/devices/system/cpu/cpu0/cpufreq




    Regards

    Jai Prakash

  • Hi,

    echo "mem" > /sys/power/state

    PM: Syncing filesystems ... done.
    Freezing user space processes ... (elapsed 0.01 seconds) done.
    Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
    Suspending console(s) (use no_console_suspend to debug)

    Type any character on console to wakeup.

    Wakeup can be done by lot of triggers/events.

    1) through RTC

    2) Configure any GPIO (push button) pin for wakeup alarm through linux device driver (wakeup irq API)

    if (device_may_wakeup(dev))
    ret = enable_irq_wake(info->irq);

    Note:

    Need to write a driver

    3) UART

    and also didn't find directory called cpufreq in the following path and its subdirectories and files how to make it visible in userspace to make changes

    Enable all the Power management related stuffs in linux through menuconfig.

    Please refer the following TI wiki for power management.

    http://processors.wiki.ti.com/index.php/AM335x_Linux_Power_Management_User_Guide
    http://processors.wiki.ti.com/index.php/AM335x_Power_Management_Standby_User%27s_Guide
    http://processors.wiki.ti.com/index.php/AM335x_Power_Management_User_Guide
    http://processors.wiki.ti.com/index.php/Sitara_Linux_Training:_Power_Management

    Note

    Please refer your device manual & data sheet to check supported types of power management by your device.

  • Hi,

         Thanks for earlier replies. I don't have much exp in that field i.e i am asking questions

     Configure any GPIO (push button) pin for wakeup alarm through linux device driver (wakeup irq API)

    if (device_may_wakeup(dev))
    ret = enable_irq_wake(info->irq);

    But i want to know where i should make change so that my board wakes up from freez mode when running command ----->  echo mem > /sys/power/state and where i would register intrerrupt and how to register need help regarding interrupts from basics  is there any pdf to follow for waking my gpio's, currently on my board i am using gpio pins from 48 ..........55 using these pins i have to wake up my device(mem)

    i tried that :-

    static struct gpio_keys_button ev_keys[] = {
                 {
                      .code           = -1,
                      .gpio           = HAWK_KEYPAD_PIN15,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "MASTER Tamper Button",
                      .type           = EV_KEY,
              },
              {
                      .code           = -1,
                      .gpio           = HAWK_KEYPAD_PIN14,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "GPIO Battery Status",
                      .type           = EV_KEY,
              },
                 {
                      .code           = -1,
                      .gpio           = HAWK_KEYPAD_PIN13,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "MASTER Input Button",
                      .type           = EV_KEY,
              },
              {
                     .code           = -1,
                      .gpio           = 51,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "SLAVE Input Button",
                      .type           = EV_KEY,
              },
              {
                      .code           = -1,
                      .gpio           = 52,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "MASTER LED",
                      .type           = EV_KEY,
              },
               {
                      .code           = -1,
                      .gpio           = 54,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "SLAVE LED",
                      .type           = EV_KEY,
              },
              {
                      .code           = -1,
                      .gpio           = 53,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "SLAVE Tamper Button",
                      .type           = EV_KEY,
              },
              {
                      .code           = -1,
                      .gpio           = 55,
                      .active_low     = 1,
                      .wakeup         = 1,
                      .desc           = "REDUNDANCY TEST",
                      .type           = EV_KEY,
              },

    };

    static struct gpio_keys_platform_data calixto_board_gpio_keys_data = {
        .buttons = ev_keys,
        .nbuttons = ARRAY_SIZE(ev_keys),
    };

    static struct platform_device calixto_keys_device = {
               .name   = "gpio-keys-jp",
              .id     = -1,
                .dev    = {
                    .platform_data  = &calixto_board_gpio_keys_data,
                },
    };

    but didn't get sucedded, need help asap.

  • Hi Kumar,

    First, You need to write one module driver for accessing GPIO to interrupt, then make that interrupt for wake able.

    1) I have attached one sample (GPIO to irq) module driver and do some pinmuxing for GPIO 55 and insert the (.ko)module in your linux.

    2) Push the button which is configured to GPIO55.

    3) Check whether the interrupt is raised or not (printk).

    Now modify your source for wakeup interruptible .

    /*
     * Sample driver for making GPIO to interrupt
     *
     * This file is subject to the terms and conditions of the GNU General Public
     * License.
     *
     * AUTHOR : Titusrathinaraj Stalin
     * EMAIL  : x0213399@ti.com
     *	
     */
    
    
    
    /* Include linux kernel header files */
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/fs.h>
    #include <linux/cdev.h>
    #include <asm/uaccess.h>
    #include <linux/device.h>
    #include <asm/gpio.h>
    #include <linux/interrupt.h>
    #include <asm/irq.h>
    #include <linux/sched.h>
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Titus S");
    MODULE_DESCRIPTION("GPIO interrupt sample driver");
    
    #define GPIO_INT 55	/* GPIO No 55 */
    
    /* local functions */
    static int gpio_irq_open (struct inode *inode, struct file *filp);
    static int gpio_irq_release (struct inode *inode, struct file *filp);
    static int gpio_irq_fasync(int fd, struct file *filp, int on);
    
    static struct fasync_struct *gpio_irq_async_queue;
    
    /* declare file operation structure */
    static struct file_operations gpio_irq_fops = {
    	.owner = THIS_MODULE,
    	.open  = gpio_irq_open,
    	.release = gpio_irq_release,
    	.fasync	= gpio_irq_fasync,
    };
    
    /*Interrupt Handler */
    static irqreturn_t gpio_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    {
    	printk("\n GPIO interrupt raised; IRQ No : %d\n",irq);
    	kill_fasync(&gpio_irq_async_queue, SIGIO, POLL_IN);
    	return IRQ_HANDLED;
    }
    
    /***************************************************************************
     * Function             - gpio_request_irq
     * Functionality        - Registers Handlers to the IRQ's of GPIO's by request_irq
     * Input Params - 
     * Return Value - None
     * Note                 - None
     ****************************************************************************/
    void gpio_request_irq(int irq_num)
    {
    	int status = 0;
    
    	status = request_irq(irq_num, gpio_interrupt,IRQF_SHARED,"gpio_int", 102); //we can use IRQF_DIABLED
    
    	printk(KERN_WARNING "gpio_request_irq %d status %d\n",
    			   irq_num, status);
    
    	if (status == -EINVAL) {
    		printk("<1> EINVAL \n");
    		} 
    	else if (status == -ENOMEM) {
    		printk("<1> ENOMEM ");
    		} 		
    		
    	if (status < 0) {
    		printk("<1> gpio_request_irq : Failed to Register IRQ %d  \n",
    		       irq_num);
    		printk("<1> gpio_request_irq : return status is %d  \n",
    		       status);
    	}
    
    }
    
    /***************************************************************************
     * Function             - gpio_unrequest_irq
     * Functionality        - Free Handlers o the IRQ's of GPIO's
     * Input Params - 
     * Return Value - None
     * Note                 - None
     ****************************************************************************/
    void gpio_unrequest_irq(int irq_num)
    {
    	free_irq(irq_num, 102);
    	printk("<1> gpio_unrequest_irq :  Freeing IRQ %d  \n", irq_num);
    
    }
    /****************************************************************************/
    
    
    static int gpio_irq_fasync(int fd, struct file *filp, int on)
    {
    	int temp;
    	temp = fasync_helper(fd, filp, on, &gpio_irq_async_queue);
    	if (fd != -1)
    		kill_fasync(&gpio_irq_async_queue, SIGIO, POLL_IN);
    	return(temp);
    }
    
    void hhtp_gpio_init(void)
    {
    //	unsigned int *PINMUX3 = ioremap(0x01c40010,4); 
    //	unsigned int control,tmp;
    //	control = (*PINMUX3) | 0x00010000; //for GPIO18 (16th bit)
    //	*PINMUX3 = control;
    
    // TODO : Need to pinmux for GPIO55 here
    
    	gpio_direction_input(GPIO_INT);
    	tmp = gpio_to_irq(GPIO_INT);
    	printk(KERN_ALERT "IRQ is %d\n",tmp);
    	gpio_request_irq(tmp);
    }
    
    /******************************************************************************
     * gpio_irq_open - do nothing 
     *****************************************************************************/
    static int gpio_irq_open (struct inode *inode, struct file *filp)
    {
        return 0;
    }    
    
    /******************************************************************************
     * gpio_irq_release - do nothing 
     *****************************************************************************/
    static int gpio_irq_release (struct inode *inode, struct file *filp)
    {
    	if (filp->f_flags & FASYNC) {
    		gpio_irq_fasync (-1, filp, 0);
    	}
    	return 0;
    } 
    
    /*****************************************************************************
     * initialise user gpio module
     ****************************************************************************/
    static int gpio_irq_init(void)
    {
    	unsigned int status,status1;
    
    	status = register_chrdev(102, "gpio_int", &gpio_irq_fops);
    	printk(KERN_ALERT "GPIO IRQ device is inserted sucessfully");
    		  if (status < 0) {
    		  printk(KERN_ALERT "Registering char device failed with %d\n", status);
    		  return status;
    }    
    	status1 = gpio_request(GPIO_INT, "gpio_int");
    	printk(KERN_ALERT "gpio request o/p is %d\n",status1);
    
    	hhtp_gpio_init();
    	return 0;
    }
    
    /*****************************************************************************
     * cleanup user gpio module
     ****************************************************************************/
    static void gpio_irq_exit(void)
    {
    	unregister_chrdev(102, "gpio_int");
    	gpio_unrequest_irq(gpio_to_irq(GPIO_INT));
    	printk(KERN_ALERT "GPIO IRQ device is ejected sucessfully");
    }
    
    module_init(gpio_irq_init);
    module_exit(gpio_irq_exit);
    

    obj-m	+= gpio_irq.o
    
    all:
    	make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -C  /home/titus/workdir/ti-e2e/src/DaVinci-PSP-SDK-03.22.00.02/src/kernel/linux-davinci M=`pwd` modules
    clean:
    	make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -C  /home/titus/workdir/ti-e2e/src/DaVinci-PSP-SDK-03.22.00.02/src/kernel/linux-03.22.00.02 M=`pwd` clean
    
    

    I will update with full implementation for logicPD EVM  once done.

    mean while change this code for your linux kernel version like Changing include declaration file locations (2.6.33).

  • Hi stalin,

                     I want to know about the path ----->        /home/titus/workdir/ti-e2e/src/DaVinci-PSP-SDK-03.22.00.02/src/kernel/linux-davinci

      I am using my own Makefile which i have attached also set enviormental variables like export -----> CC=arm-none-linux-gnueabi-       and

    INSTALLDIR= $(shell pwd)/modules
    ifneq ($(KERNELRELEASE),)
    	obj-m := gpio_int.o
    gpio_int_mod-objs := gpio_int.o
    
    else
    	KERNDIR ?= /lib/modules/$(shell uname -r)/build
    	PWD := $(shell pwd)
    
    default:
    	$(MAKE) -C $(KERNDIR) M=$(PWD) modules
    	@rm -rf $(INSTALLDIR)
    	@mkdir $(INSTALLDIR)
    	@mv *.ko *.mod.c *.o .*.cmd $(INSTALLDIR)
    
    clean:
    	rm -rf $(INSTALLDIR)
    
    endif
    
    
       export ARCH=arm  ,  My gpio_int.c and Makefile are in /homejaiprakash/gpio , also I make a makefile executable from chmod but when i give a make  command  it gives error like this

    root@JAIPRAKASH:~/gpio# make
    make -C /lib/modules/2.6.32-55-generic/build M=/home/jaiprakash/gpio/modules
    make[1]: Entering directory `/usr/src/linux-headers-2.6.32-55-generic'
    make[1]: *** /usr/src/linux-headers-2.6.32-55-generic/arch/arm: Is a directory.  Stop.
    make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-55-generic'
    make: *** [default] Error 2

  • Hi,

    make[1]: Entering directory `/usr/src/linux-headers-2.6.32-55-generic'

    It is the default kernel location for your linux host machine and not for ARM linux kernel.

    You have to mention linux source path which you are going to boot and already builded.

    I have taken kernel image "uImage" from /home/titus/workdir/ti-e2e/src/DaVinci-PSP-SDK-03.22.00.02/src/kernel/linux-davinci/arch/arm/boot/uImage  to boot and insert the module driver.

    Use my make file and just modify the kernel location.

    obj-m    += gpio_irq.o

    all:
        make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-  -C  < kernel location>  M=`pwd` modules

    clean:
        make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-    -C <kernel location>  M=`pwd` clean

  • Hi,

    Try this for wakeup from suspend mode through timer

    To wakeup, Do programming the wakeup timer before asserting suspend.

    target$ mkdir /debug

    target$ mount -t debugfs debugfs /debug

    target$ echo -n 3 > /debug/pm_debug/wakeup_timer_seconds

    The suspend for device can be asserted as follows,

    echo "mem" -n > /sys/power/state

    The device will get wakeup after 3 sec as programmed.