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.

TMDSCSK8127: TMS320DM8127 memory-mapped registers read/write operation

Part Number: TMDSCSK8127

I work with TMDSCSK8127 board and use IPNC-RDK-CSK  (3_9_1)

I need to change and read PLLSS (and any other) register values from the terminal

As I understand, linux_prcm_ipcam work with registers using the WR_MEM_32(addr, data) to directly write into register

and RD_MEM_32(addr) to directly  read from register

I added the next code that lets me choose an adress for read/write register operation
to /ipnc_rdk-3.9.1/Source/ipnc_rdk/ipnc_app/utils/prcm_app/linux_prcm_ipcam

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


if(0==strcmp(argv[1],"rd"))    //read reg value operation
    {
    if(argc>2)
        {

        RD_MEM_32((int)strtol(argv[2],NULL,16));
        
        }
    
    }
    
    
    else
    if(0==strcmp(argv[1],"wr"))    //write reg value operation
    {
        if(argc>3)
            {
        int reg=(int)strtol(argv[2],NULL,16);
        int val=(int)strtol(argv[3],NULL,16);
        printf("WRITE reg %p val %p  \n",reg,val);
        WR_MEM_32(reg,   val);
        RD_MEM_32(reg);    //look a result of write reg operation
            }
        
    }
    else
    switch (argv[1][0]) {

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

I run it on target from terminal.
I test it on 0x48180D10 RM_ISP_RSTCTRL register:
read the reg value,then write other value to the reg address,
read the reg value again and find that
write operation at this reg was succesful:

------------------------------------------------------------------------------------------------------------
root@ti81xx:/opt/ipnc# ./linux_prcm_ipcam rd 0x48180D10
/dev/mem opened.
             Phy Addr : 0x48180d10 Data : 0x00000007
root@ti81xx:/opt/ipnc# ./linux_prcm_ipcam wr 0x48180D10 3
/dev/mem opened.
WRITE reg 0x48180d10 val 0x3  
             Phy Addr : 0x48180d10 Data : 0x00000003
------------------------------------------------------------------------------------------------------------

Than, after reboot, I tried to implement the steps to re-configurethe VIDEO1PLL

e2e.ti.com/.../1161204

using "/linux_prcm_ipcam wr" from terminal:

1. write VIDEO1PLL_CLKCTRL[23] IDLE = 1 //thus you start transition from locked/active to bypass/idle mode

PLLSS Peripheral Registers base address: 0x481C_5000 (Table 3-6 of TMS320DM8127 DaVinci Video Processors datasheet (Rev.C))
VIDEO1PLL_CLKCTRL offset:  1D4h    (Table 2-42 MS320DM814x DaVinci Digital Media Processors Technical Reference Manual (SPRUGZ8))           
------------------------------------------------------------------------------------------------------------
root@ti81xx:/opt/ipnc# ./linux_prcm_ipcam rd 0x481C51D4
             Phy Addr : 0x481c51d4 Data : 0x08910811
------------------------------------------------------------------------------------------------------------
So, VIDEO1PLL_CLKCTRL[23] IDLE = 1

2. wait while VIDEO1PLL_STATUS[8] BYPASSACK == 1 and VIDEO1PLL_STATUS[0] BYPASS == 1
VIDEO1PLL_CLKCTRL offset:  1F4h
------------------------------------------------------------------------------------------------------------
root@ti81xx:/opt/ipnc# ./linux_prcm_ipcam rd 0x481C51F4
             Phy Addr : 0x481c51f4 Data : 0xe0000161
------------------------------------------------------------------------------------------------------------
So, IDEO1PLL_STATUS[8] BYPASSACK == 1 and VIDEO1PLL_STATUS[0] BYPASS == 1

3. clear bit VIDEO1PLL_CLKCTRL[0] TINITZ = 0
------------------------------------------------------------------------------------------------------------
root@ti81xx:/opt/ipnc# ./linux_prcm_ipcam wr 0x481C51D4 0x08910810                                      
/dev/mem opened.
WRITE reg 0x481c51d4 val 0x8910810  
             Phy Addr : 0x481c51d4 Data : 0x08910811
------------------------------------------------------------------------------------------------------------
So, I tried to change value of IDEO1PLL_STATUS reg and it failed, value does not changed.

How should I work with PLLSS memory-mapped registers to change their value?

Can I work from linux_prcm_ipcam with any memory-mapped register?

  • Hi Gl88,

    Yes, linux_prcm_ipcam can be used to access (read/write) DM8127 memory mapped registers from user space. You can also use devmem2 and/or omapconf tools.


    For the correct sequence of changing PLL settings, please refer to the below e2e post:

    Regards,
    Pavel

  • I test the next code based on code from ti_tools/hdvpss_01_00_01_37/docs/ti814x/TI814x_ES_2x_evm_A8_ddr3.gel

    ------------------------------------------------------------
    cmdVIDEO1PLL(int CLKIN,int N, int M, int M2)
    {
            DCOCLK_COMP(CLKIN,N,M);
            if(HSMODE == 2){   
                PLL_Clocks_Config(VIDEO_1_PLL_BASE,CLKIN,N,M,M2,ADPLLJ_CLKCRTL_HS2);  
             //    GEL_TextOut("\t VIDEO-1 ADPLLJ CLKOUT  value is  = %d \n",,,,,CLKOUT);
            }
            else if (HSMODE == 1){
                PLL_Clocks_Config(VIDEO_1_PLL_BASE,CLKIN,N,M,M2,ADPLLJ_CLKCRTL_HS1);  
            //     GEL_TextOut("\t VIDEO-1 ADPLLJ CLKOUT  value is  = %d \n",,,,,CLKOUT);
            }
            else {
             //         GEL_TextOut("\t VIDEO-1 PLL NOT Configured.Wrong DCOCLK Output\n");
            }
     
    }

    DCOCLK_COMP(int CLKIN,int N, int M)
     {
             int DCOCLK;
            DCOCLK = (CLKIN/(N+1))*M;
            
            if(DCOCLK >= 500 && DCOCLK < 1000){
                    HSMODE = 2;  //HS2 Mode  
            }
            else if(DCOCLK >= 1000 && DCOCLK < 2000){
                    HSMODE = 1;  //HS1 Mode
            }
            else HSMODE = 0;  //wrong configuration
            
            //return HSMODE;
     }

    PLL_Clocks_Config(UWORD32 Base_Address,UWORD32 CLKIN,UWORD32 N,UWORD32 M,UWORD32 M2,UWORD32 CLKCTRL_VAL)
    {
        PRINT("[1]\n");
        UWORD32 m2nval,mn2val,read_clkctrl,clk_out,ref_clk,clkout_dco = 0;
        m2nval = (M2<<16) | N;
        mn2val =  M;
        ref_clk     = CLKIN/(N+1);
        clkout_dco  = ref_clk*M;
        clk_out     = clkout_dco/M2;

        unsigned int val;

        RD_MEM_32(Base_Address+CLKCTRL);
        val=RD_MEM_32(Base_Address+CLKCTRL)& 0xfffffffe;
        PRINT("val 0x%X",val);        
        WR_MEM_32(Base_Address+CLKCTRL, val);
        RD_MEM_32(Base_Address+CLKCTRL);    

        PRINT("[2]\n");
        while (( (RD_MEM_32(Base_Address+STATUS)) & 0x00000101) != 0x00000101);


    PRINT("[3]\n");
        RD_MEM_32(Base_Address+CLKCTRL);
        val=RD_MEM_32(Base_Address+CLKCTRL)& 0xfffffffe;
        PRINT("val 0x%X\n",val);
        WR_MEM_32(Base_Address+CLKCTRL, val); //TINITZ=0
        RD_MEM_32(Base_Address+CLKCTRL);

        wait_delay(3);
    PRINT("[4]\n");
        RD_MEM_32(Base_Address+M2NDIV );
        val=m2nval;
        PRINT("val 0x%X\n",val);
        WR_MEM_32((Base_Address+M2NDIV    ),val); //write N value
        RD_MEM_32(Base_Address+M2NDIV );

    PRINT("[5]\n");
        RD_MEM_32(Base_Address+M2NDIV );
        val=mn2val;
        PRINT("val 0x%X\n",val);
        WR_MEM_32((Base_Address+MN2DIV    ),val);
        RD_MEM_32(Base_Address+M2NDIV );

        wait_delay(3);

    PRINT("[6]\n");
        RD_MEM_32(Base_Address+TENABLEDIV);
        val=0x1;
        PRINT("val 0x%X\n",val);
        WR_MEM_32((Base_Address+TENABLEDIV),val);
        RD_MEM_32(Base_Address+TENABLEDIV);

        wait_delay(3);

    PRINT("[7]\n");
        RD_MEM_32(Base_Address+TENABLEDIV);
        val=0x0;
        PRINT("val 0x%X\n",val);
        WR_MEM_32((Base_Address+TENABLEDIV),val);
        RD_MEM_32(Base_Address+TENABLEDIV);

        wait_delay(3);

    PRINT("[8]\n");
        RD_MEM_32(Base_Address+TENABLE);
        val=0x1;
        PRINT("val 0x%X\n",val);
        WR_MEM_32((Base_Address+TENABLE   ),val);
        RD_MEM_32(Base_Address+TENABLE);

        wait_delay(3);

    PRINT("[9]\n");
        RD_MEM_32(Base_Address+TENABLE);
        val=0x0;
        PRINT("val 0x%X\n",val);
        WR_MEM_32((Base_Address+TENABLE   ),val);
        RD_MEM_32(Base_Address+TENABLE);

        wait_delay(3);

        read_clkctrl = RD_MEM_32(Base_Address+CLKCTRL);

        //configure the TINITZ(bit0) and CLKDCO BITS IF REQUIRED

    PRINT("[10]\n");
        RD_MEM_32(Base_Address+TENABLE);
        val=(read_clkctrl & 0xff7fe3ff) | CLKCTRL_VAL;
        PRINT("val 0x%X\n",val);
        WR_MEM_32(Base_Address+CLKCTRL,val); //TINITZ = 1
        RD_MEM_32(Base_Address+TENABLE);

        read_clkctrl = RD_MEM_32(Base_Address+CLKCTRL);

        // poll for the freq,phase lock to occur

    PRINT("[11]\n");

        while (( (RD_MEM_32(Base_Address+STATUS)) & 0x00000600) != 0x00000600);

        //wait fot the clocks to get stabized
        wait_delay(10);
    PRINT("[12]\n");
        CLKOUT    = clk_out;
    }
        

    int main(int argc, char **argv)
    {
        unsigned int addr, data;

        if(argc < 2) {
          PRINT("GZ 5 Usage: %s [a|p|s|c|t|r|l]\n",  argv[0]);
          /* a - All
           * p - print
           * s - set
           * c - compare
           */
          exit(1);
        }

        if((us_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
          PRINT ("Could not open the mem file \n");//FATAL;
        }

        
        if(0==strcmp(argv[1],"change_VIDEO1PLL"))    //write reg value operation
        {
        //PRINT ("change_VIDEO1PLL\n");
        cmdVIDEO1PLL(CLKIN,19, 600,4);
        }

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

    And get the next result:

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

    root@ti81xx:/opt/ipnc# ./linux_prcm_ipcam change_VIDEO1PLL
    [1]
                 Phy Addr : 0x481c51d4 Data : 0x08910811
                 Phy Addr : 0x481c51d4 Data : 0x08910811
    val 0x8910810             Phy Addr : 0x481c51d4 Data : 0x08910811

    Here I read from reg and print it,

    then print the value to write,

    Write value to the reg

    And read from reg again

    And I see that I can not write to the reg sucsessfully - the register value has not changed ufter write operation


    [2]
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
    [3]
                 Phy Addr : 0x481c51d4 Data : 0x08910811
                 Phy Addr : 0x481c51d4 Data : 0x08910811
    val 0x8910810             Phy Addr : 0x481c51d4 Data : 0x08910811
    [4]
                 Phy Addr : 0x481c51e0 Data : 0x00050013
    val 0x40013             Phy Addr : 0x481c51e0 Data : 0x00050013
    [5]
                 Phy Addr : 0x481c51e0 Data : 0x00050013
    val 0x258             Phy Addr : 0x481c51e0 Data : 0x00050013
    [6]
                 Phy Addr : 0x481c51dc Data : 0x00000000
    val 0x1             Phy Addr : 0x481c51dc Data : 0x00000000
    [7]
                 Phy Addr : 0x481c51dc Data : 0x00000000
    val 0x0             Phy Addr : 0x481c51dc Data : 0x00000000
    [8]
                 Phy Addr : 0x481c51d8 Data : 0x00000000
    val 0x1             Phy Addr : 0x481c51d8 Data : 0x00000000
    [9]
                 Phy Addr : 0x481c51d8 Data : 0x00000000
    val 0x0             Phy Addr : 0x481c51d8 Data : 0x00000000
                 Phy Addr : 0x481c51d4 Data : 0x08910811
    [10]
                 Phy Addr : 0x481c51d8 Data : 0x00000000
    val 0x8110811             Phy Addr : 0x481c51d8 Data : 0x00000000
                 Phy Addr : 0x481c51d4 Data : 0x08910811
    [11]
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161
                 Phy Addr : 0x481c51f4 Data : 0xe0000161

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

  • WR_MEM_32 successfully works with PM_ISP_PWRSTCTRL register and some others.

    Why the WR_MEM_32 does not work with PLLSS memory-mapped registers?

  • Gl88,

    I can provide you below suggestions:

    1. Try with devmem2 tool or application based on devmem2 source code

    2. Check if you have the correct value in PLLSS_MMR_LOCK register. For more info refer to DM8127 TRM Table 2-42. PLLSS REGISTERS, section 2.10.1.4 PLLSS_MMR_LOCK Register and below e2e post:

    3. Try to access these registers from u-boot or kernel space. Some device registers needs Cortex-A8 ARM to be in Supervisor privilege mode, which is valid for u-boot/kernel, but not in user space

    Regards,
    Pavel

  • Pavel, thank You for support.

    Yes, I found that I can work with this registers from u-boot and can not do it from user space.

    How can I access device registers from kernel space?

    do I need write any kernel module or driver to achieve this?

  • Yes, you can modify these registers from kernel source or through external loadable kernel module. Check below pointers for more info:

    For read/write registers in kernel space, you should translate the physical address to virtual. Check below e2e thread for details:

    e2e.ti.com/.../1202037

    Regards,
    Pavel

  • What are the ways to enter the supervisor mode from user mode?

  • The only way I can think of is to load external kernel module. This is linux generic question, not TI specific, I would suggest you to check in generic linux forums.

    Regards,
    Pavel