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.

Can't change pin mux in Linux

I have a DM8148 running 2.6.37 Linux kernel.

I am trying to change pinmuxing from userspace program ran with root access.

I am able to read the pinmuxing but I can not write.  Nothing errors out, it just doesn't change the value when I read it back.

 My code is below, please help.

target = 0x48140B10; //Touch_int
target2 = 0x48140AF0; //Touch_rst
value = 0x00050080;
/* Map one page */
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
if(map_base == (void *) -1) {
printf("Memory map failed.\n");
} else {
printf("Memory mapped at address %p.\n", map_base);
}
fflush(stdout);


virt_addr = map_base + target - (target & ~MAP_MASK);
virt_addr2 = map_base + target2 - (target2 & ~MAP_MASK);
/* acess remapped region here */
int read_result, read_result2, new_result, new_result2;
read_result = *((volatile unsigned long *) virt_addr);
read_result2 = *((volatile unsigned long *) virt_addr);

*((volatile unsigned long *) virt_addr) = value;
*((volatile unsigned long *) virt_addr2) = value;

msync(map_base, MAP_SIZE, MS_SYNC);
new_result = *((volatile unsigned long *) virt_addr);
new_result2 = *((volatile unsigned long *) virt_addr);

printf(" Was %08x , %08x\n", read_result, read_result2 );
printf(" Set to %08x , %08x\n", value, value);
printf("Now %08x, %08x\n", new_result, new_result2);

  • I believe  this behaviour is expected. PINMUX register write are protected by MMR_LOCK which can be unlocked only when processor is in supervisor mode. I think you would have to write a kernel driver if you want to change pinmux settings or do the change in uboot.

     

  • Ok thanks for response...I'll try to do it in driver and let you know what happens.

  • Yes, I was able to change pinmuxing from driver.

    Thanks.

  • Badri can you provide assistance with my post here:

    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/226070.aspx

  • Hi Badri,

    My customer find that they can't modify PINMUX reg under linux user mode, while it works under kernel mode.

    Is the ARM supervisor correspond to the linux kernel mode ? It looks like the MMR_lock reg actually an ARM register ?

    Is it possible to set kind of register to pull ARM into supervisor mode to simplify the SW development other than kernel driver?

    BR

    Eason

  • DVR RDK 4.0 includes a /dvr_rdk/bin/ti816x/kermod/prot_reg_rdwr.ko kernel module which can be used to read and modify protected mode registers. You can insmod this driver and use it

  • Hi Badri,

    I am trying to change sata pll registers value using devmem2 and later mem_rdwr

    These utilities don't output failure message on writing, but when reading the same register I see that the value did not change. Is it from the same reason above ?

    Is there a way to use prot_reg_rdwr.ko from console ?

    root@dm814x:/opt/dvr_rdk/ti814x/bin# ./mem_rdwr.out --wr 48140720 12345678

    ORG 0x48140720: 40007077
    NEW 0x48140720: 40007077

    root@dm814x:~# devmem2 0x48140720 w 0xc0007077
    /dev/mem opened.
    Memory mapped at address 0x4005c000.
    Read at address 0x48140720 (0x4005c720): 0x40007077
    Write at address 0x48140720 (0x4005c720): 0xC0007077, readback 0xC0007077
    root@dm814x:~# devmem2 0x48140720
    /dev/mem opened.
    Memory mapped at address 0x40252000.
    Read at address 0x48140720 (0x40252720): 0x40007077

    Thanks,

    Ran

  • The proto_reg_rdwr.ko is meant ot be used from console. Usage is documented in the readme.txt present in

    /dvr_rdk/mcfw/src_linux/utils/prot_reg_rdwr/README.txt

    Reproduced below

    * Make sure DebugFS is mounted. If not follow steps below to mount it.
    
      mount -t debugfs null /sys/kernel/debug
    
    * Do "insmod prot_reg_rdwr.ko" to insert the .ko. This is NOT done by default in DVRRDK
    
    * Now you should see the prot_reg_debug entry in the following location
    
      /sys/kernel/debug/prot_reg/mem
    
    * To write to system space
    
      echo "w <start_address> <data> <count>" > /sys/kernel/debug/prot_reg/mem
    
      start_address : From where to start writing (in hex format i.e. 0xAA55AA55)
      data		: 32-bit data to be written (in hex format i.e. 0xAA55AA55)
      count		: Number of location to repeat the data (in decimal format)
    
      example
      -------
      1. echo "w 0x48140b34 0x2 1" > /sys/kernel/debug/prot_reg/mem
    
    	This would write 0x2 to one location starting from 0x48140b34
    
      2. echo "w 0x48140b34 0x2 10" > /sys/kernel/debug/prot_reg/mem
    
    	This would write 0x2 to ten locations starting from 0x48140b34.
    	So locations 0x48140b34 through 0x48140b58 would have 0x2
    
    * To read from system space
    
      echo "r <start_address> <count>" > /sys/kernel/debug/prot_reg/mem
    
      Start printing the contents starting from <start_address> and end after
      <count> times.
    
     example
     -------
     1. echo "r 0x48140b34 1" > /sys/kernel/debug/prot_reg/mem
    
    	Print the contents of location 0x48140b34
    
     2. echo "r 0x48140b34 10" > /sys/kernel/debug/prot_reg/mem
    
    	Print contents of 10 location starting from 0x48140b34.
    	So locations 0x48140b34 through 0x48140b58 will be printed.