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.

66AK2H14: Changing ARM frequency on Keystone 2 evaluation board

Part Number: 66AK2H14
Other Parts Discussed in Thread: 66AK2H12

Hi TI,

I would like to change ARM CPU frequency on Keystone 2 66AK2H12/66AK2H14 evaluation board from 1.4 GHz to lower value. How do I go about doing it?
Currently I am running VxWorks. I thought lowering CPU frequency can be achieved from board UBOOT prompt (NOT from VxWorks boot prompt), but with multiple attempts of constantly hitting "ESC"
key during board power up I am not able to stop at UBOOT prompt. Is there any other way of changing ARM frequency? or if UBOOT is the way, what is the key sequence to get to prompt?

Please advise, 

Thank you

Jerry

  • Jerry,

    For changing the ARM frequency, please refer this E2E thread.

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/534926/how-to-know-cpu-frequency-in-keystone---2

    To stop at u-boot prompt, "Hit any key to stop autoboot: " ( within 2 to 3 seconds)

    Refer the last screenshot in this FAQ:[FAQ] 66AK2E05: How to flash the u-boot into SPI of K2E ?? using PROCESSOR-SDK-LINUX-K2E - Processors forum - Processors - TI E2E support forums

    Regards

    Shankari G

  • Jerry

    I have attached a pdf below. Go to the section, " How to change Tetris and Core PLL speed " and check.

    4401.MCSDK UG Chapter Exploring - Texas Instruments Wiki.pdf

    Regards

    Shankari G

  • Hi Shankari, 

    Thank you very much for you reply. 

    I believe the first issue I need to overcome is to get into U-BOOT prompt. Currently there is no U-BOOT autoboot countdown, when the board powers up it jumps directly from U-BOOT to VXWorks Boot. "Hitting" any key at the time between screen displaying U-BOOT info and VXWorks boot does not interrupt the jump (neither keep on "hitting" key before the screen displays U-BOOT info). Would you have any suggestions how to stop from jump to VxWorks boot?

    Regards

    Jerry 

  • Jerry,

    VXworks ? Is it a part of TI software package?  If yes, please mention the name of the software package and its version.

    Regards

    Shankari G

  • Hi Shankari,

    No, VxWorks is not part of TI software package. From different perspective is there another way to modify Core PLL speed, maybe via direct register configuration instead U-BOOT? Looking into 66AK2Hxx Multicore DSP+ARM® KeyStoneTm II System-on-Chip (SoC) (SPRS866G –NOVEMBER 2012–REVISED OCTOBER 2017) Table 11-28, would ARM frequency change by setting PLLD,PLLM and BOOTMODE values directly into registers?

    Regards

    Jerry

  • Jerry,

    Yes, possible through register settings. 

    It is given here in the K2H gel file:-7180.xtcievmk2x_arm.gel

    --

    ARM PLL @

    * 100 MHz to 1.0 GHz operation
    * 100 MHz to 1.4 GHz operation
    * 175 MHz to 1.4 GHz operation

    --

    // Setup main PLL index = 3 -> 122.88 MHz to 983.04 MHz operation
    Set_Pll1(3);

    // Setup ARM PLL index = 1 -> 125 MHz to 1000 MHz operation
    Set_Tetris_Pll(1);

    --

    if(index == 1){ // 125 MHz -> 1.0 GHz
            CLKIN_val = 125; // setup CLKIN to 125 MHz
           PLLM_val = 16; // setup PLLM (PLL multiplier) to x20
           OD_val = 2; // setup OD to a fixed /2
    }
    else if(index == 2){ // 125 MHz -> 1.4 GHz
           CLKIN_val = 125; // setup CLKIN to 125 MHz
           PLLM_val = 22; // setup PLLM (PLL multiplier) to x28
           OD_val = 2; // setup OD to a fixed /2
    }
    else if(index == 3){ // 174.825MHz -> 1.4 GHz

           CLKIN_val = 174.825; // setup CLKIN to 174.825 MHz
           PLLM_val = 16; // setup PLLM (PLL multiplier) to x16
           OD_val = 2; // setup OD to a fixed /2
    }

    //********************************************************************************************************************************
    //********************************************************************************************************************************
    /*
       Set_Pll1() - This function executes the main PLL initialization 
       sequence needed to get the main PLL up after coming out of an initial power up 
       before it is locked or after it is already locked.
    
       Index value determines multiplier, divier used and clock reference assumed for 
       output display. 
     */
    Set_Pll1(int index)
    {
        int i, TEMP;
        unsigned int BYPASS_val;     
        unsigned int BWADJ_val;     
        unsigned int OD_val;            
    
        float CLKIN_val;
        unsigned int PLLM_val;
        unsigned int PLLD_val;
        unsigned int PLLDIV3_val; //example value for SYSCLK2 (from 6614 spec) Default /2 - Fast Peripherals, (L2, MSMC, DDR3 EMIF, EDMA0...)
        unsigned int PLLDIV4_val; //example value for SYSCLK3 (from 6614 spec) Default /3 - Switch Fabric
        unsigned int PLLDIV7_val; //example value for SYSCLK6 (from 6614 spec) Defualt /6 - Slow Peripherals (UART, SPI, I2C, GPIO...)
    
        unsigned int debug_info_on;
        unsigned int delay;
    
    	if(index == 1){            // 122.88 MHz -> 614.4 MHz
            CLKIN_val   = 122.88;       // setup CLKIN to 122.88 MHz
            PLLM_val    = 10;           // setup PLLM (PLL multiplier) to x10
            PLLD_val    = 1;            // setup PLLD (reference divider) to /1
            OD_val      = 2;            // setup OD to a fixed /2
    		}
    	else if(index == 2){            // 122.88MHz -> 737.28 MHz
            CLKIN_val   = 122.88;       // setup CLKIN to 122.88 MHz
            PLLM_val    = 12;           // setup PLLM (PLL multiplier) to x12
            PLLD_val    = 1;            // setup PLLD (reference divider) to /1
            OD_val      = 2;            // setup OD to a fixed /2
        }
    	
    	else if(index == 3){            // 122.88MHz -> 983.04 MHz
            CLKIN_val   = 122.88;       // setup CLKIN to 122.88 MHz
            PLLM_val    = 16;           // setup PLLM (PLL multiplier) to x12
            PLLD_val    = 1;            // setup PLLD (reference divider) to /1
            OD_val      = 2;            // setup OD to a fixed /2
        }
    	
    	else if(index == 4){            // 122.88 MHz -> 1.2 GHz
            CLKIN_val   = 122.88;          // setup CLKIN to 122.88 MHz
            PLLM_val    = 625;           // setup PLLM (PLL multiplier) to x625
            PLLD_val    = 32;            // setup PLLD (reference divider) to /32
            OD_val      = 2;            // setup OD to a fixed /2
        }
        else if(index == 5){            // 122.88 MHz -> 1.228 GHz
            CLKIN_val   = 122.88;          // setup CLKIN to 122.88 MHz
            PLLM_val    = 20;           // setup PLLM (PLL multiplier) to x20
            PLLD_val    = 1;            // setup PLLD (reference divider) to /1
            OD_val      = 2;            // setup OD to a fixed /2
        }
        
    	 
    	 
        
        PLLDIV3_val = 3;            // setup PLL output divider 3 to /3
        PLLDIV4_val = 5;            // setup PLL output divider 4 to /3
        PLLDIV7_val = 6;            // setup PLL output divider 7 to /6
    
        BYPASS_val      = PLL1_SECCTL & ~BYPASS_MASK;   // get value of the BYPASS field
        BWADJ_val       = (PLLM_val) >> 1;              // setup BWADJ to be 1/2 the value of PLLM
        OD_val          = 2;                            // setup OD to a fixed /2
    
        debug_info_on   = 1;
        delay           = 1000; // fix this!
    
        /* Step 1: Unlock Boot Config Registers */
        KICK0 = KICK0_UNLOCK;
        KICK1 = KICK1_UNLOCK;
    
        /* Step 2: Check if SECCTL bypass is low or high indicating what state the Main PLL is currently in. if 
           the Main PLL is in bypass still (not yet setup) execute the following steps.  */
    
        if(BYPASS_val != 0x00000000){ // PLL bypass enabled - Execute PLL setup for PLL fresh out of power on reset
            if(debug_info_on){
                GEL_TextOut("Detected PLL bypass enabled: SECCTL[BYPASS] = %x\n",,,,, BYPASS_val);
            }
            /* Step 2a: Set MAINPLLCTL1[ENSAT] = 1 - This enables proper biasing of PLL analog circuitry */            
            MAINPLLCTL1 |= (1 << MAIN_ENSAT_OFFSET); 
            if(debug_info_on){
                GEL_TextOut("(2a) MAINPLLCTL1 = %x\n",,,,, MAINPLLCTL1);
            }        
    
            /* Step 2b: Set PLLCTL[PLLEN] = 0 This enables bypass in PLL controller MUX */        
            PLL1_PLLCTL &= ~(1 << PLLEN_OFFSET);        
            if(debug_info_on){    
                GEL_TextOut("(2b) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
            }    
    
            /* Step 2c: Set PLLCTL[PLLENSRC] = 0 - This enables PLLEN to control PLL controller MUX */    
            PLL1_PLLCTL &= ~(1 << PLLENSRC_OFFSET);
            if(debug_info_on){    
                GEL_TextOut("(2c) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
            }    
    
            /* Step 2d: Wait 4 reference clock cycles (slowest of ALTCORE or SYSCLK) to make sure 
               that the PLL controller MUX switches properly to bypass. */
            if(debug_info_on){    
                GEL_TextOut("(2d) Delay...\n",,,,,);
            }        
            for(i = 0; i < delay; i++); // this delay is much more than required         
    
            /* Step 2e: Set SECCTL[BYPASS] = 1 - enables bypass in PLL MUX */    
            PLL1_SECCTL |= (1 << BYPASS_OFFSET);        
            if(debug_info_on){    
                GEL_TextOut("(2e) SECCTL = %x\n",,,,, PLL1_SECCTL);
            }    
    
            /* Step 2f: Set PLLCTL[PLLPWRDN] = 1 - power down the PLL */        
            PLL1_PLLCTL |= (1 << PLLPWRDN_OFFSET);
            if(debug_info_on){    
                GEL_TextOut("(2f) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
            }    
    
            /* Step 2g: Wait for at least 5us for the PLL to power down */
            if(debug_info_on){    
                GEL_TextOut("(2g) Delay...\n",,,,,);
            }    
            for(i = 0; i < delay; i++); // this delay is much more than required 
    
            /* Step 2h: Set PLLCTL[PLLPWRDN] = 0 - Power the PLL back up */    
            PLL1_PLLCTL &= ~(1 << PLLPWRDN_OFFSET);
            if(debug_info_on){    
                GEL_TextOut("(2h) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
            }            
    
        }
        else{ // PLL bypass disabled - Execute PLL setup for PLL that has previously been locked (skip to Step 3)
            if(debug_info_on){    
                GEL_TextOut("Detected PLL bypass disabled: SECCTL[BYPASS] = %x\n",,,,, BYPASS_val);
            }
    
            /* Step 3a: Set PLLCTL[PLLEN] = 0 This enables bypass in PLL controller MUX */        
            PLL1_PLLCTL &= ~(1 << PLLEN_OFFSET);        
            if(debug_info_on){    
                GEL_TextOut("(3a) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
            }    
    
            /* Step 3b: Set PLLCTL[PLLENSRC] = 0 - This enables PLLEN to control PLL controller MUX */    
            PLL1_PLLCTL &= ~(1 << PLLENSRC_OFFSET);
            if(debug_info_on){    
                GEL_TextOut("(3b) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
            }
    
            /* Step 3c: Wait 4 reference clock cycles (slowest of ALTCORE or SYSCLK) to make sure 
               that the PLL controller MUX switches properly to bypass. */
            if(debug_info_on){    
                GEL_TextOut("(3c) Delay...\n",,,,,);
            }        
            for(i = 0; i < delay; i++); // this delay is much more than required       
    
        }
    
    
        /* Step 4: Programming PLLM[5:0] in the PLLM register of the PLL controller and
           programming PLLM[12:6] in the MAINPLLCTL0 register */        
        PLL1_PLLM &= PLLM_MASK;             // clear the PLLM[5:0] bit field
        PLL1_PLLM |= ~PLLM_MASK & (PLLM_val - 1);   // set the PLLM[5:0] bit field to the 6 LSB of PLLM_val
    
        if(debug_info_on){
            GEL_TextOut("(4)PLLM[PLLM] = %x\n",,,,, PLL1_PLLM);
        }    
    
        MAINPLLCTL0 &= MAIN_PLLM_MASK;      // clear the PLLM[12:6] bit field
        MAINPLLCTL0 |= ~MAIN_PLLM_MASK & (( (PLLM_val - 1) >> 6) << MAIN_PLLM_OFFSET);  // set the PLLM[12:6] bit field to the 7 MSB of PLL_val
    
        if(debug_info_on){
            GEL_TextOut("MAINPLLCTL0 = %x\n",,,,, MAINPLLCTL0);
        }
    
        /* Step 5: Programming BWADJ[7:0] in the MAINPLLCTL0 register and BWADJ[11:8] in MAINPLLCTL1 register */            
        MAINPLLCTL0 &= MAIN_BWADJ0_MASK;    // clear the MAIN_BWADJ0 bit field
        MAINPLLCTL0 |= ~MAIN_BWADJ0_MASK & ((BWADJ_val - 1) << MAIN_BWADJ0_OFFSET); // set the MAIN_BWADJ[7:0] bit field to the 8 LSB of BWADJ_val
    
        if(debug_info_on){
            GEL_TextOut("(5) MAINPLLCTL0 = %x\n",,,,, MAINPLLCTL0);
        }
    
        MAINPLLCTL1 &= MAIN_BWADJ1_MASK;    // clear the MAIN_BWADJ1 bit field
        MAINPLLCTL1 |= ~MAIN_BWADJ1_MASK & (( (BWADJ_val - 1) >> 8) << MAIN_BWADJ1_OFFSET); // set the MAIN_BWADJ[11:8] bit field to the 4 MSB of BWADJ_val
    
        if(debug_info_on){
            GEL_TextOut("(5) MAINPLLCTL1 = %x\n",,,,, MAINPLLCTL1);
        }
    
        /* Step 6: Programming PLLD[5:0] in the MAINPLLCTL0 register */            
        MAINPLLCTL0 &= MAIN_PLLD_MASK;      // clear the PLLD bit field
        MAINPLLCTL0 |= ~MAIN_PLLD_MASK & (PLLD_val - 1);    // set the PLLD[5:0] bit field of PLLD to PLLD_val
    
        if(debug_info_on){
            GEL_TextOut("(6) MAINPLLCTL0 = %x\n",,,,, MAINPLLCTL0);
        }
    
        /* Step 7: Programming OD[3:0] in the SECCTL register */            
        PLL1_SECCTL &= OUTPUT_DIVIDE_MASK;  // clear the OD bit field
        PLL1_SECCTL |= ~OUTPUT_DIVIDE_MASK & (OD_val - 1) << OUTPUT_DIVIDE_OFFSET;  // set the OD[3:0] bit field of PLLD to OD_val    
    
        if(debug_info_on){
            GEL_TextOut("(7) SECCTL = %x\n",,,,, PLL1_SECCTL);
        }
    
        /* Step 8: Following steps are needed to change the default output dividers */            
    
        /* Step 8a: Check that the GOSTAT bit in PLLSTAT is cleared to show that no GO
           operation is currently in progress*/
        if(debug_info_on){    
            GEL_TextOut("(8a) Delay...\n",,,,,);
        }    
        while((PLL1_STAT) & 0x00000001);
    
        /* Step 8b: Program the RATIO field in PLLDIVn to the desired new divide-down rate.
           If RATIO field is changed, the PLL controller will flag the change in the
           corresponding bit of DCHANGE*/
        PLL1_DIV3 = (PLLDIV3_val-1) | 0x8000;  //Set PLLDIV3
        PLL1_DIV4 = (PLLDIV4_val-1) | 0x8000;  //Set PLLDIV4
        PLL1_DIV7 = (PLLDIV7_val-1) | 0x8000;  //Set PLLDIV7
    
        if(debug_info_on){
            GEL_TextOut("PLL1_DIV3 = %x\n",,,,, PLL1_DIV3);
            GEL_TextOut("PLL1_DIV4 = %x\n",,,,, PLL1_DIV4);
            GEL_TextOut("PLL1_DIV7 = %x\n",,,,, PLL1_DIV7);
        }
    
        /* Step 8c: Set GOSET bit in PLLCMD to initiate the GO operation to change the divide
           values and align the SYSCLKs as programmed */
        PLL1_CMD |= 0x00000001;
    
        /*Step 8d/e: Read the GOSTAT bit in PLLSTAT to make sure the bit returns to 0 to
          indicate that the GO operation has completed */
        if(debug_info_on){    
            GEL_TextOut("(8d/e) Delay...\n",,,,,);
        }    
        while((PLL1_STAT) & 0x00000001);
        
        /* Step 9: Set PLLCTL[PLLRST] = 1 - Assert PLL reset (Previously Step 3)*/        
        PLL1_PLLCTL |= (1 << PLLRST_OFFSET);
    
        /* Step 10: Wait for the at least 7us for the PLL reset properly (128 CLKIN1 cycles) */        
        if(debug_info_on){    
            GEL_TextOut("(10) Delay...\n",,,,,);
        }    
        for(i=0;i<delay;i++);
    
        /* Step 11: Set PLLCTL[PLLRST] = 0 - De-Assert PLL reset */        
        PLL1_PLLCTL &= ~(1 << PLLRST_OFFSET);
    
        /* Step 12: Wait for PLL to lock (2000 CLKIN1 cycles) */
        if(debug_info_on){    
            GEL_TextOut("(12) Delay...\n",,,,,);
        }    
        for(i=0;i<delay;i++);
    
        /* Step 13: In SECCTL, write BYPASS = 0 (enable PLL mux to switch to PLL mode) */
        PLL1_SECCTL &= ~(1 << BYPASS_OFFSET);        
        if(debug_info_on){    
            GEL_TextOut("(13) SECCTL = %x\n",,,,, PLL1_SECCTL);
        }    
    	 if(debug_info_on){    
            GEL_TextOut("(Delay...\n",,,,,);
        }    
    	 for(i=0;i<delay;i++);
    	 if(debug_info_on){    
            GEL_TextOut("(Delay...\n",,,,,);
        }    
    	 for(i=0;i<delay;i++);
    
        /* Step 14: In PLLCTL, write PLLEN = 1 to enable PLL mode */
        PLL1_PLLCTL |= (1 << PLLEN_OFFSET);        
        if(debug_info_on){    
            GEL_TextOut("(14) PLLCTL = %x\n",,,,, PLL1_PLLCTL);
        }    
    
        /* Step 15: Lock Boot Config Registers */
        KICK0 = 0x00000000;
        KICK1 = 0x00000000;
    
        GEL_TextOut("PLL has been configured (CLKIN * PLLM / PLLD / PLLOD = PLLOUT):\n",,,,,);
        GEL_TextOut("PLL has been configured (%f MHz * %d / %d / 2 = %f MHz)\n",,,,, CLKIN_val, PLLM_val, PLLD_val, (CLKIN_val * PLLM_val / PLLD_val / 2) );
    
    }
    
    
    
    Set_Tetris_Pll(int index)
    {
    
        unsigned int BWADJ_val;     
        unsigned int OD_val;            
        unsigned int PLLM_val;
        float CLKIN_val;
        int i;
    
        GEL_TextOut("Switching on ARM Core 0\n",,,,,);
        TETRIS_CPU0_PDCTL   = 0x00000000;
        TETRIS_CPU0_PTCMD   = 0x00000001;    
    
        GEL_TextOut("Switching on ARM Core 1\n",,,,,);
        TETRIS_CPU1_PDCTL   = 0x00000000;
        TETRIS_CPU1_PTCMD   = 0x00000001;    
        
        GEL_TextOut("Switching on ARM Core 2\n",,,,,);
        TETRIS_CPU2_PDCTL   = 0x00000000;
        TETRIS_CPU2_PTCMD   = 0x00000001;    
        
        GEL_TextOut("Switching on ARM Core 3\n",,,,,);
        TETRIS_CPU3_PDCTL   = 0x00000000;
        TETRIS_CPU3_PTCMD   = 0x00000001;
    
           if(index == 1){              // 125 MHz -> 1.0 GHz
            CLKIN_val   = 125;          // setup CLKIN to 125 MHz
            PLLM_val    = 16;           // setup PLLM (PLL multiplier) to x20
            OD_val      = 2;            // setup OD to a fixed /2
        }
        else if(index == 2){            // 125 MHz -> 1.4 GHz
            CLKIN_val   = 125;          // setup CLKIN to 125 MHz
            PLLM_val    = 22;           // setup PLLM (PLL multiplier) to x28
            OD_val      = 2;            // setup OD to a fixed /2
        }
        else if(index == 3){            // 174.825MHz -> 1.4 GHz
    
            CLKIN_val   = 174.825;      // setup CLKIN to 174.825 MHz
            PLLM_val    = 16;           // setup PLLM (PLL multiplier) to x16
            OD_val      = 2;            // setup OD to a fixed /2
        }
    
        BWADJ_val       = (PLLM_val-1) >> 1;            // setup BWADJ to be 1/2 the value of PLLM
        OD_val          = 2;                            // setup OD to a fixed /2
    
        /* Step 1: Unlock Boot Config Registers */
        KICK0 = KICK0_UNLOCK;
        KICK1 = KICK1_UNLOCK;
    
    	/* Step 1: Unlock Boot Config Registers */
    	CHIP_MISC1 &= ~(1 << ARMPLL_ENABLE_OFFSET);
    	
        //Step 2 and 6 : Assert SEC PLL Reset
        ARMPLLCTL1 = ((1 << ARM_PLLCTL1_RESET_OFFSET) | (1 << ARM_PLLCTL1_ENSTAT_OFFSET));
    	
    	//Step 3 : set PLL in bypass
    	ARMPLLCTL0 |= (1 << ARM_PLLCTL0_BYPASS_OFFSET);
    
        //Step 4 and 5 : Change CLKF/OD/BWADJ etc. for SEC PLL
        ARMPLLCTL0 = ((BWADJ_val << ARM_PLLCTL0_BWADJ_OFFSET) |
                      ((OD_val-1) << ARM_PLLCTL0_OD_OFFSET)|
                      ((PLLM_val-1) << ARM_PLLCTL0_PLLM_OFFSET));
    
        //Step 7 : Make sure the resets are held for 5us
        for(i = 0; i < 200000; i++);
    
        //Step 8 : Remove SEC PLL reset
        ARMPLLCTL1 = (1 << ARM_PLLCTL1_ENSTAT_OFFSET);   //This drives ARM_PLL1_RESET_OFFSET = 0
    
        //Step 9 : Wait for PLL to lock (4000 CLKIN1 cycles)
        for(i = 0; i < 4000; i++);
    
        //Step 10 : Get the PLL out of Bypass
        ARMPLLCTL0 &= ~(1 << ARM_PLLCTL0_BYPASS_OFFSET);
    	
        //Step 11 : Set Output of ARM PLL as input to ARM
        CHIP_MISC1 |= (1 << ARMPLL_ENABLE_OFFSET); 
    
    
    	
        //Step 11: Lock Boot Config Registers
        KICK0 = 0x00000000;
        KICK1 = 0x00000000;  
        
        GEL_TextOut("ARM PLL has been configured (%f MHz * %d / %d = %f MHz)\n",,,,, CLKIN_val, PLLM_val, OD_val, (CLKIN_val * PLLM_val)/OD_val);
    
    }
    

    Regards

    Shankari G