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.

I2C clocking - sysclk10 appears to be 220Mhz not 48Mhz on DM8148

I am trying to get i2c working on the 8148 with a custom driver.  My understanding of most of the code out there that 48Mhz should be getting fed in to the i2c module.  You prescale it down to 12Mhz, then set your high and low scaler values to get the desired i2c clk.

My target right now is 100Khz.  But I have to use a prescaler value of 17, scll = 60, sclh=60 to get that to work out to 100Khz.  That implies that the functional clock feeding the i2c is actually 220Mhz.  I'm failing to see the clocking configurations that should lead the SYSCLK10 to be 220Mhz or 48Mhz.  I see the sysclk10 register, but it supposed to be zeroed out on reset, or passthrough.

I am using a gel file to initialize the board, so the the rom first stage bootloader normally set this divider to something other than default?

  • Hi Justin,

    According to our Data Manual in Table 7-25. Maximum SYSCLK Clock Frequencies, the SYSCLK10 freq is 48MHz so you will need to use diff SYSCLK if you want to run above that.

    BR,

    Viet

  • I don't want to run above that.  I don't know why my sysclk10 would be anything other than 48Mhz, but I have to have my prescaler set to 17 to get a I2C clock of 12 which isn't  right.  And from what I can tell, I have no way to control what frequency is fed in to the i2c module.

    I am using a CYE1 part so I didn't know if there is any possibility of a silicon problem if it is truely supposed to be fixed t 48Mhz in hardware.  Otherwise, what configuration registers do I need to check to ensure it is configured for 48Mhz?

  • Justin,

    Have you try to config this CM_SYSCLK10_CLKSEL Register?  It has the divider but only can go lower than 48MHz.

    BR,

    Viet

  • I haven't touched that register, it is the default from reset.  So that doesn't explain why my sysclk10 appears to be running at a frequency higher than 48Mhz.  After a closer look, I adjusted my prescalers and scalers to make sure my i2c was 12Mhz, and what I come up with is this:

    I get a 100Khz I2C SCL (clk) when my prescaler is set to 19 and my scll=55 and sclh=53.  If I work the calculations backwards to see what sysclk is coming in to the I2C at:

    100khz * (55 + 7 + 53 + 5) = I2C_CLK = 12Mhz * (19+1) = 240Mhz.  

    So, its acting like the /5 is not actually happening on this chip.  Is there another way to verify 48Mhz is indeed 48Mhz at a register level?

  • Justin,

    This is what I think it should be for:

    scll=55 and sclh=53

    SYSCLK10 = 48MHz

    PSC = 19

    SCL periodcycle = [1 / (48MHz / 20)] * (55 + 7 + 53 + 5) = 0.00005

    SCL freq = 1/(SCL period cycle) = 20 KHz.

    How do you get 100 KHz?

    BR,

    Viet

  • I guess you're not understanding me fully:  Simply put, Something is wrong.

    When I apply the above mentioned settings psc=19, scl=55, sclh=53, I would expect 20KHz like you said, but I actually  measure 100KHz with an oscilloscope on the actual pin.

    I don't understand HOW this could even be possible.

  • Hi Justin,

    You can check what is your sysclk10 value using the Clock framework clk_get_rate() function:

    http://processors.wiki.ti.com/index.php/TI81XX_PSP_PM_CLOCK_FRAMEWORK_User_Guide#Get_clock_current_rate

    To get the current frequency/rate of the clock, use the clock pointer(clkp) acquired through clk_get(),

    unsigned long clk_rate;

    clk_rate = clk_get_rate(clkp);

    Other possible approach is using the clock debug fs:

    http://processors.wiki.ti.com/index.php/TI81XX_PSP_PM_CLOCK_FRAMEWORK_User_Guide#Browsing_DebugFs_for_Clock_configuration

    example:

    root@ti8168-evm:/sys/kernel/debug/clock/osc0_clkin_ck/dsp_dpll_ck/gem_fck# cat rate 500000000

    The sysclk10 value on my own DM814x is 48MHz :

    root@dm814x-evm:/sys/kernel/debug/clock/osc0_clkin_ck/usb_dpll_clkin_ck/usb_dpll_ck/usb_dpll_clk2_ck/sysclk10_ck# cat rate
    48000000

    Regards,
    Pavel
  • Are there any registers can I look at?  I am not using linux.

  • Hi Justin,

    The sysclk10 is derived from the DPLL_USB. The DPLL_USB is supplied from the device oscillator DEVOSC, which is 20MHz. The output of the DPLL_USB (CLKOUT) should be 960 MHz. Please provide me the values of the following registers:

    DEVOSC

    OSC_SRC

    USBPLL_PWRCTRL

    USBPLL_CLKCTRL

    USBPLL_TENABLE

    USBPLL_TENABLEDIV

    USBPLL_M2NDIV

    USBPLL_MN2DIV

    USBPLL_FRACDIV

    USBPLL_BWCTRL

    USBPLL_FRACCTRL

    USBPLL_STATUS

    I will compare with mine.

    Regards,

    Pavel

  • Here are my register settings.

    DEVOSC = 0

    OSC_SRC = 0

    USBPLL_PWRCTRL = 0x30

    USBPLL_CLKCTRL = 0x281B0811

    USBPLL_TENABLE = 0

    USBPLL_TENABLEDIV = 0

    USBPLL_M2NDIV = 0x00010013

    USBPLL_MN2DIV = 0x000003C0

    USBPLL_FRACDIV = 0x04000000

    USBPLL_BWCTRL = 0x0

    USBPLL_FRACCTRL = 0x0

    USBPLL_STATUS = 0xC0000630

  • Also, if what you say is true, then 960Mhz / 5 = 192Mhz != 48Mhz.   Where should the div 4 be coming from?

  • And to anticipate your next question:

    CM_SYSCLK10_CLKSEL = 0x3 which I guess is where my /4 is coming from.  I'm confused where the /5 is supposed to be coming from and if there is a way to disable it in the PLL_USB block...because it appears to be disabled on my board, but my understanding is that there is no way to disable this /5

  • I just pulled down the latest datasheet, and there is no mention of a /5 anymore SPRS647D.

    Figure 7-6, System Clocking Overview:
    Section 7.4
    • Deleted fixed /5 divider from PLL_USB CLKOUT signal to PRCM [Applicable to Silicon Revision
    Clocking
    1.0 only]

    I have a CYE1 part so do I assume that means the /5 is removed for me?  And yet the rest of the datasheet indicates the clock is still fixed at 48Mhz for SYSCLK10.  So is the /5 removed in later silicon or not?  My two options right now are to at least us /8 in the sysclk10 prcm and get a 120Mhz, and a prescale of 9 (9+1) divider for i2c.  Or just leave it be and keep my prescaler at 19.  I am using USB 2.0, so I need the USB_PLL at 960Mhz.

    And yet page 455 in SPRUGZ8C mentions something about a "192 MHz(User programmed /5)"

    Can you help straighten this out for me.  What should I be expecting?

  • The /5 divider is at device level (not at PRCM level), and it is fixed. It can not be controlled by the software (through registers configuration). But as you notice, there is a possibility that this /5 divider is removed for DM814x device, silicon revision 1.0.

    My DM814x device is silicon revision 2.1, and it has the /5 divider. Thus the frequency goes to 192MHz. After that the ROM Code is configuring the CM_SYSCLK10_CLKSEL = 0x3 (/4) {see DM814x TRM, Table 4-7. ROM Code Default Clock Settings - (PLL_USB/5)/4}. Thus finally I have the 48Mhz source for the I2C module.

    The silicon revision is determined from the DEVICE_ID[31:28] DEVREV bit field. The DEVICE_ID register is at address 0x48140600. What is the DEVREV value for your device? If it is not equal to 0x3, 0xC or 0x4, then it is 1.0 revision and the /5 is removed (I will double check this with our datasheet team).

    Here is the u-boot source code, that is responsible for determine the device silicon revision:

    /******************************************
     * get_cpu_rev(void) - extract rev info
     ******************************************/
    u32 get_cpu_rev(void)
    {
        u32 id;
        u32 rev;

        id = readl(DEVICE_ID);
        rev = (id >> 28) & 0xF;

    #ifdef CONFIG_TI814X
        /* PG2.1 devices should read 0x3 as chip rev
         * Some PG2.1 devices have 0xc as chip rev
         */
        if (0x3 == rev || 0xc == rev)
            return PG2_1;
        else if (0x4 == rev)
            return PG3_0;
        else
            return PG1_0;
    #endif
        return rev;
    }

    Comparing the differences with my USB_DPLL registers, we have only one (but important) difference. My value for the USBPLL_M2NDIV is 0x00050013, which means that my M2 value is 0x5, while your M2 value is 0x1.

    Can you try with the 0x00050013 value?

    Regards,

    Pavel

     

  • Pavel,

    Thanks for your help.  Last night I didn't get a chance to post my findings.  Then I saw your post and found it ironic.  

    Reading between the lines in Figure 2-8 in SPRUGZ8C I realized that there are two lines coming out of the DPLL_USB.  One of which was labeled CLKDCOLDO.  I recently had done some work writing my own pll routines and that rung a bell and that it was odd that it was the dco stage that was being used to drive the USB ref clk, but then I thought maybe the other output that is NOT labeled might be the normal CLKOUT of the the PLL and that M2 was the /5 that was depicted everywhere.  Indeed it was.  I then noticed that my gel file was changed along the way to assume the USB CLKOUT needed to be 960 and M2 was then set to /1.

    So....the lessen is:

    the /5 IS sw programmable, but it is indeed the M2 divider of the DPLL_USB, and that the USB doesn't actually use the clkout, but rather a dco tap on the pll.  the PLL_USB M2 is assumed to be set to 5 to generate a clkout at 192Mhz which then feeds the SYSCLK10 divider which is assumed to be /4.  The ROM must normally be setting the sysclk10 divider to /4 because out of reset it is only /2.  

    Lessen 2: The datasheet says sysclk10 is a fixed 48Mhz which isn't remotely true.  To get 48Mhz, it assumes USB DCO has been configured to 960Mhz.  Then it assumes M2 of the PLL is set to 5.  Then it assumes that CM_SYSCLK10_CLKSEL is set to /4...THEN I get a 48Mhz to feed in to my I2C functional block.

  • Hi Justin,

    I also think the /5 divider is actually the (embedded into the DPLL_USB, not at device level) M2 divider. Glad you resolve the issue.

    Regards,

    Pavel

  • The concept of a fixed 48Mhz as indicated in the datasheet is a complete misnomer and really through me off.  And the latest datasheet diagrams implied it was user configurable, which seemed contradictory, but it never said how. Oh well.  

  • I will report this to the DS/TRM team, and will be fixed for the next documentation release.

    Regards,

    Pavel