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.

Clock ratio between CORE_CLKOUTM4(IEP) and CORE_CLKOUTM5(Ether)

Other Parts Discussed in Thread: AM3358

I'm planning to create synchronized system using PTP and IEP clock.

So, I want to know the exact frequency ratio between PTP hardware timestamp and IEP clock.

According to Figure 8-10. Core PLL of AM335x Technical Reference Manual (spruh73m.pdf):
PTP hardware timestamp is created from CORE_CLKOUTM5,
IEP clock is created from CORE_CLKOUTM4.

I observed the accumulation of difference between:
- IEP clock x 5 and clock_gettime(CLOCK_REALTIME)
- more than 300 msec difference after 9000 secs observation, 34 usec / sec.
- This difference is caused by the MPU Subsystem PLL. ARM-A8 core frequency is created from CORE_CLKOUTM6 via PLL.
- IEP clock x 5 and PTP hardware timestamp
- less than 10 usec difference during 9000 secs observation.
- Nano sec value of PTP hardware timestamp is always multiple of 4. (increased by 4 at each 250MHz clock)
- frequency ratio between CORE_CLKOUTM4(200MHz) and CORE_CLKOUTM5(250MHz) seems exactly 4:5.

If the ratio between IEP clock and PTP hardware timestamp is exactly the simple integer,
it is easy to mapping the 2 clock domains.

Please let me know the actual implementation.

  • What processor are you using? In your post you refer the AM335X TRM, yet you have tagged AM437X.
  • Hi Biser,

    Thank you for your reply.
    Sorry, I made the mistake to select tags.

    I'm using AM3358, BeagleBone Black.

    Regards.
    TOMINAGA Satoshi
  • Thanks for the clarification. I will ask the factory team to comment on this.
  • CLKOUTM4/M5/M6 frequencies should always be 200/250/500MHz respectively for CORE OPP100 operation.  The MPU runs off of a completely different PLL (MPU PLL),  whose frequency depends on MPU OPP. 

    The M6 that you see in the CORE PLL diagram does go to the MPU PLL, but it is only used potentially in low power situations (ie, it is rarely used).

    Regards,

    James    

  • Hi JJD,

    Sorry for my late reply because of Japanese "Golden week" holidays.

    > CLKOUTM4/M5/M6 frequencies should always be 200/250/500MHz respectively for CORE OPP100 operation. 

    I need one more confirmation.

    Do you mean that the following assumption is correct? I'm planning to implement

    the application which needs exact synchronize between PTP (IEEE1588) and IEP clock

    over .weeks or months.

    If the ratio of CORE_CLKOUTM4 and CORE_CLKOUTM5 is fixed but not 200000000 : 250000000,

    I want to know the exact ratio (e.g, 200000001 : 249999999), according to the HSDIVIDER  circuit.

    > - frequency ratio between CORE_CLKOUTM4(200MHz) and CORE_CLKOUTM5(250MHz) seems exactly 4:5.

    > If the ratio between IEP clock and PTP hardware timestamp is exactly the simple integer

    ,

    Regards,

    TOMINAGA Satoshi

  • Hi James,

    Thank you for your support.

    I want to confirm the exact ratio of CORE_CLKOUTM4 and CORE_CLKOUTM5.
    Is it just 200000000 : 250000000 ?
    If not, I want to know the precise value according to the HSDIVIDER circuit.

    Regards,
    TOMINAGA Satoshi
  • Yes, it is 4:5 if the dividers are set accordingly to produce CORE_CLKOUTM4=200MHz and CORE_CLKOUTM5=250MHz.

    Regards,
    James
  • Hi James,

    Thank you for your reply.

    To confirm the CM_WKUP registers, I used the following program.
    The result of TI SDK v02.00.01.07 is:

    OFFSET_CM_DIV_M4_DPLL_CORE: 0000022A
    - [9] ST_HSDIVIDER_CLKOUT1: 1: gated
    - [5] HSDIVIDER_CLKOUT1_DIVCHACK: 1: Toggle on this status bit after changing HSDIVIDER_CLKOUT1_DIV
    - [4:0] HSDIVIDER_CLKOUT1_DIV: 10: POST Divider, 2000MHz / 10 = 200MHz
    OFFSET_CM_DIV_M5_DPLL_CORE: 00000228
    - [9] ST_HSDIVIDER_CLKOUT2: 1: gated
    - [5] HSDIVIDER_CLKOUT2_DIVCHACK: 1: Toggle on this status bit after changing HSDIVIDER_CLKOUT2_DIV
    - [4:0] HSDIVIDER_CLKOUT2_DIV: 8: POST Divider, 2000MHz / 8 = 250MHz
    OFFSET_CM_DIV_M6_DPLL_CORE: 00000004
    - [9] ST_HSDIVIDER_CLKOUT3: 0: enabled
    - [5] HSDIVIDER_CLKOUT3_DIVCHACK: 0: Toggle on this status bit after changing HSDIVIDER_CLKOUT3_DIV
    - [4:0] HSDIVIDER_CLKOUT3_DIV: 4: POST Divider, 2000MHz / 4 = 500MHz

    The HSDIVIDER_CLKOUT_DIV values match the description in Table 8-22. Core PLL Typical Frequencies.
    But I wonder that the ST_HSDIVIDER_CLKOUT1 and ST_HSDIVIDER_CLKOUT2 are 1 (gated), even PTP hardware clock and PRU (IEP clock) are working.
    Are they proper values?

    Checking C++ Code:

    #define ADDR_CM    0x44E00000
    #define SIZE_CM    0x1000
    #define OFFSET_CM_DIV_M4_DPLL_CORE    (0x480)
    #define OFFSET_CM_DIV_M5_DPLL_CORE    (0x484)
    #define OFFSET_CM_DIV_M6_DPLL_CORE    (0x4D8)
    
    int main(){
        int fd = open("/dev/mem",O_RDWR | O_SYNC);
        ulong* wakeup =  (ulong*) mmap(NULL, SIZE_CM, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ADDR_CM);
    
        if (wakeup == MAP_FAILED){
            printf("Failed to MMAP. errno:(%d) %s\n", errno, strerror(errno));
            close(fd);
            return 1;
        } else {
            printf("Success mapping to %p\n", wakeup);
        }
    
        printf("OFFSET_CM_DIV_M4_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M4_DPLL_CORE/sizeof(ulong)]);
        printf("OFFSET_CM_DIV_M5_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M5_DPLL_CORE/sizeof(ulong)]);
        printf("OFFSET_CM_DIV_M6_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M6_DPLL_CORE/sizeof(ulong)]);
    
        close(fd);
    
        return 0;
    }

    Regards,
    TOMINAGA Satoshi

  • James-san,

    Could you please reply Tominaga-san's latest question?

    Thanks and Best regards,

    Kenichi

  • Tominaga-san,
    those dividers have automatic clock gating features which will gate the clock when it is not needed. To disable this feature, see HSDIVIDER_CLKOUTx_GATE_CTRL (bit 8) in each register. After disabling it, you should see the clock enabled all the time.

    Regards,
    James
  • 
    

    Hi James,

    I've checked the register value when bit8 is enabled.
    But the ST_HSDIVIDER_CLKOUT bit indicates that the CLKOUT is still gated.

    The environment is follows:
    - Using TI SDK v02.00.01.07
    - Both PRU0/1 are working, both firmware monitors IEP counter
    - PTP application uses hardware supported ptp via phc, ptp synchronization is established.

    The result is:

    root@am335x-evm:~/bin# ./mmap_cm_wakeup
    Success mapping to 0xb6f40000
    Before Enabling HSDIVIDER CLKOUT
    OFFSET_CM_DIV_M4_DPLL_CORE: 0000022A
    OFFSET_CM_DIV_M5_DPLL_CORE: 00000228
    OFFSET_CM_DIV_M6_DPLL_CORE: 00000004
    After Enabling HSDIVIDER CLKOUT
    OFFSET_CM_DIV_M4_DPLL_CORE: 0000032A
    OFFSET_CM_DIV_M5_DPLL_CORE: 00000328
    OFFSET_CM_DIV_M6_DPLL_CORE: 00000004

    I want to know why the ST_HSDIVIDER_CLKOUT bit of M4/M5 indicates "1: gated" even PRU / IEEE1588 are working.

    The current code is follows:

    #define ADDR_CM	0x44E00000
    #define SIZE_CM	0x1000
    #define OFFSET_CM_DIV_M4_DPLL_CORE	(0x480)
    #define OFFSET_CM_DIV_M5_DPLL_CORE	(0x484)
    #define OFFSET_CM_DIV_M6_DPLL_CORE	(0x4D8)
    using namespace std;
    
    int main(){
    	int fd = open("/dev/mem",O_RDWR | O_SYNC);
    	ulong* wakeup =  (ulong*) mmap(NULL, SIZE_CM, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ADDR_CM);
    
    	if (wakeup == MAP_FAILED){
    		printf("Failed to MMAP. errno:(%d) %s\n", errno, strerror(errno));
    		close(fd);
    		return 1;
    	} else {
    		printf("Success mapping to %p\n", wakeup);
    	}
    
    	printf("Before Enabling HSDIVIDER CLKOUT\n");
    	printf("  OFFSET_CM_DIV_M4_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M4_DPLL_CORE/sizeof(ulong)]);
    	printf("  OFFSET_CM_DIV_M5_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M5_DPLL_CORE/sizeof(ulong)]);
    	printf("  OFFSET_CM_DIV_M6_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M6_DPLL_CORE/sizeof(ulong)]);
    
    	/* Control gating of HSDIVIDER CLKOUT */
    	wakeup[OFFSET_CM_DIV_M4_DPLL_CORE/sizeof(ulong)] |= 0x00000100;
    	wakeup[OFFSET_CM_DIV_M5_DPLL_CORE/sizeof(ulong)] |= 0x00000100;
    
    	printf("After Enabling HSDIVIDER CLKOUT\n");
    	printf("  OFFSET_CM_DIV_M4_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M4_DPLL_CORE/sizeof(ulong)]);
    	printf("  OFFSET_CM_DIV_M5_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M5_DPLL_CORE/sizeof(ulong)]);
    	printf("  OFFSET_CM_DIV_M6_DPLL_CORE: %08X\n", wakeup[OFFSET_CM_DIV_M6_DPLL_CORE/sizeof(ulong)]);
    
    	close(fd);
    
    	return 0;
    }
    

    Regards,

    TOMINAGA Satoshi

  • Tominaga-san,
    I double-checked these bit definitions with our specs and it seems that the description is backward in our TRM. This is what the description should be:

    ST_HSDIVIDER_CLKOUT1
    Read 0: The clock output is gated
    Read 1: The clock output is enabled

    This is also applicable for ST_HSDIVIDER_CLKOUT2 and ST_HSDIVIDER_CLKOUT3. I will get these fixed in the next release of tehe TRM. Sorry for the confusion.

    Regards,
    James
  • Hi James,

    Thank you for your information.

    I think the meaning of the bit ST_HSDIVIDER_CLKOUT3 is different from ST_HSDIVIDER_CLKOUT1 or ST_HSDIVIDER_CLKOUT2.

    I add the following line to the source code:

    wakeup[OFFSET_CM_DIV_M6_DPLL_CORE/sizeof(ulong)] |= 0x00000100;

    The result shows that ST_HSDIVIDER_CLKOUT3 keeps 0 even HSDIVIDER_CLKOUT3_GATE_CTRL is 1.
    Please check again the difference between registers for M4 / M5 and M6.

    Before Enabling HSDIVIDER CLKOUT
    OFFSET_CM_DIV_M4_DPLL_CORE: 0000022A
    OFFSET_CM_DIV_M5_DPLL_CORE: 00000228
    OFFSET_CM_DIV_M6_DPLL_CORE: 00000004
    After Enabling HSDIVIDER CLKOUT
    OFFSET_CM_DIV_M4_DPLL_CORE: 0000032A
    OFFSET_CM_DIV_M5_DPLL_CORE: 00000328
    OFFSET_CM_DIV_M6_DPLL_CORE: 00000104

    Regards,
    TOMINAGA Satoshi

  • Hi James,

    Are there any update on this issue?

    Regards,
    TOMINAGA Satoshi