AnsweredAssumed Answered

imx233 How to correctly initialise the CPU clock?

Question asked by Chris Smith on Aug 3, 2013
Latest reply on Aug 17, 2013 by Chris Smith

Here's hoping you can help!

 

I've a project that I was running under Linux on an (olimex) imx233 board that I need to run bare, to reduce the resource use.

When I run it bare (having done all the initialisation I thought necessary), it appears much slower, as though the CPU is not running at the desired 454 MHz.

 

To prove this, I wrote the following test program to initialise the imx23 CPU clock (clk_p) to 454 MHz, set clk_h to clk_p / 3, and toggle a GPIO pin at clk_h / 8. My last round of testing seemed to indicate that clk_p was actually at 42 MHz, but I confess I've gone round and round in my testing, and have kind of lost the plot now, so 42 could be wrong!

 

I'm currently doing this without JTAG until my serial JTAG arrives.

 

This code is not a million miles away from the u-boot code. This should compile with gcc and the imx-bootlets mach-mx23/includes/ files, and boot with imxbootlets.

 

Am I right in thinking that clk_p is the CPU clock?

Can someone confirm my findings and/or point out the error of my ways????

 

Yours, really stuck,

Chris

 

#include "regsdigctl.h"
#include "regsclkctrl.h"
#include "regspower.h"
#include "regstvenc.h"
#include "regspinctrl.h"
#include "regs.h"


#define LED_OLIMEX (1 << 1)


/* -------------------------------------------------------------------------- */


void delay_us (int us)
{
    olatile int start = HW_DIGCTL_MICROSECONDS_RD();
    while (HW_DIGCTL_MICROSECONDS_RD() - start < us) { }
}


/* -------------------------------------------------------------------------- */


int main(void)
{
    unsigned int value;


    /* Configue PIO for LED */
    BW_PINCTRL_MUXSEL4_BANK2_PIN01( 0x3 ); // Enable GPIO
    HW_PINCTRL_DOUT2_SET( LED_OLIMEX );
    HW_PINCTRL_DOE2_SET ( LED_OLIMEX );


    /* Enable PLL. */
    HW_CLKCTRL_PLLCTRL0_SET( BM_CLKCTRL_PLLCTRL0_POWER );
    delay_us(10000);


    // Change VDD to 1.550v
    value  =  HW_POWER_VDDDCTRL_RD();
    value &= ~BM_POWER_VDDDCTRL_TRG;
    value |=  BF_POWER_VDDDCTRL_TRG(30);
    HW_POWER_VDDDCTRL_WR(value);


    delay_us(10000);
    
    HW_CLKCTRL_CLKSEQ_SET( BM_CLKCTRL_CLKSEQ_BYPASS_CPU ); // Use ref_xtal


    HW_CLKCTRL_FRAC_SET( BM_CLKCTRL_FRAC_CLKGATECPU   );   // Disable ref_cpu
    HW_CLKCTRL_FRAC_SET( BM_CLKCTRL_FRAC_CPUFRAC      );   // Leave CPUFRAC set to 19
    HW_CLKCTRL_FRAC_CLR( BF_CLKCTRL_FRAC_CPUFRAC(~19) );   // by going to max, then to 19
    HW_CLKCTRL_FRAC_CLR( BM_CLKCTRL_FRAC_CLKGATECPU   );   // Enable ref_cpu @  454.736 MHz


    // Set CLK_H to (CPU) CLK_P / 3
    HW_CLKCTRL_HBUS_SET(BM_CLKCTRL_HBUS_DIV);
    HW_CLKCTRL_HBUS_CLR( ((~3)&BM_CLKCTRL_HBUS_DIV) );
    //HW_CLKCTRL_HBUS_WR( BF_CLKCTRL_HBUS_DIV(3) );


    while( HW_CLKCTRL_HBUS_RD() & BM_CLKCTRL_HBUS_BUSY )  {}


    delay_us(10000);


    HW_CLKCTRL_CLKSEQ_CLR( BM_CLKCTRL_CLKSEQ_BYPASS_CPU ); // Use ref_cpu


    // Flash LED @ clk_h / 8
    // So rate should be clk_p / (3 * 8) = 454.736 / 24 = 18.94 MHz
    //
    while(1) {
        if( HW_DIGCTL_HCLKCOUNT_RD() & 0x4  ) { // divide by 8
            HW_PINCTRL_DOUT2_SET( LED_OLIMEX );
        } else {
            HW_PINCTRL_DOUT2_CLR( LED_OLIMEX );
        }
    }
}


/* -------------------------------------------------------------------------- */


































Outcomes