#include <stdint.h>
#include <stdio.h>

#include <sys/mman.h> // for mmap()
#include <fcntl.h>    // for open()

int main ()
{
    int fd = open("/dev/mem", O_RDWR);
    off_t  slcr_base   = 0xF8000000;
    size_t slcr_length = 0x00001000;

    uint32_t *slcr_ptr = (uint32_t *)mmap(NULL, slcr_length,
            PROT_READ | PROT_WRITE, 
            MAP_SHARED, 
            fd, slcr_base);

    if (slcr_ptr == MAP_FAILED)
    {
        printf("ERROR: mmap call failed.\n");
        return 1;
    }

    int FPGA_CLK_CTRL[4] = { 0x170, 0x180, 0x190, 0x1A0 };

    for (int i = 0; i < 4; ++i)
    {
        printf("------------------------\n");
        uint32_t v = slcr_ptr[FPGA_CLK_CTRL[i]/4];

        uint32_t divisor1 = (v >> 20) & 0x3F;
        uint32_t divisor0 = (v >> 8)  & 0x3F;
        uint32_t srcsel   = (v >> 4)  & 0x03;

        printf("FPGA clk %d raw: %08X\n",i,v);
        if (srcsel < 2)
            printf("  src  : IO PLL\n");
        else if (srcsel == 2)
            printf("  src  : ARM PLL\n");
        else
            printf("  src  : DDR PLL\n");

        printf("  div0 : %d\n", divisor0);
        printf("  div1 : %d\n", divisor1);

        if (srcsel < 2) // IO PLL
        {
            int freq = 1000 / (divisor0 * divisor1);
            printf("  freq : %d MHz\n", freq);
        }
    }

    munmap(slcr_ptr,slcr_length);
    return 0;
}

