arc: emsdp: Read real CPU clock value from hardware
authorAlexey Brodkin <alexey.brodkin@synopsys.com>
Tue, 27 Nov 2018 06:46:59 +0000 (09:46 +0300)
committerAlexey Brodkin <abrodkin@synopsys.com>
Mon, 3 Dec 2018 11:26:35 +0000 (14:26 +0300)
We do real CPU clock measurement with help of built-in
counters. Thus we may accommodate different real clock values
that appear in different FPA images instead of relying on
something hard-coded in the .dtb.

And while at it make make SDIO base address define
look similar to others with casting to "(void *)".

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
board/synopsys/emsdp/emsdp.c

index b5ec7f17ec1b35c4f6a79ec639bf9497a58da6c3..5ab44353746b1b0b92cca798e12550d508663281 100644 (file)
@@ -7,10 +7,46 @@
 #include <dwmmc.h>
 #include <malloc.h>
 
+#include <asm/arcregs.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
-#define ARC_PERIPHERAL_BASE    0xF0000000
-#define SDIO_BASE              (ARC_PERIPHERAL_BASE + 0x10000)
+#define ARC_PERIPHERAL_BASE            0xF0000000
+
+#define CGU_ARC_FMEAS_ARC              (void *)(ARC_PERIPHERAL_BASE + 0x84)
+#define CGU_ARC_FMEAS_ARC_START                BIT(31)
+#define CGU_ARC_FMEAS_ARC_DONE         BIT(30)
+#define CGU_ARC_FMEAS_ARC_CNT_MASK     GENMASK(14, 0)
+#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET  0
+#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET  15
+
+#define SDIO_BASE                      (void *)(ARC_PERIPHERAL_BASE + 0x10000)
+
+int mach_cpu_init(void)
+{
+       int rcnt, fcnt;
+       u32 data;
+
+       /* Start frequency measurement */
+       writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
+
+       /* Poll DONE bit */
+       do {
+               data = readl(CGU_ARC_FMEAS_ARC);
+       } while (!(data & CGU_ARC_FMEAS_ARC_DONE));
+
+       /* Amount of reference 100 MHz clocks */
+       rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
+              CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+       /* Amount of CPU clocks */
+       fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
+              CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+       gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
+
+       return 0;
+}
 
 int board_mmc_init(bd_t *bis)
 {
@@ -24,7 +60,7 @@ int board_mmc_init(bd_t *bis)
 
        memset(host, 0, sizeof(struct dwmci_host));
        host->name = "Synopsys Mobile storage";
-       host->ioaddr = (void *)SDIO_BASE;
+       host->ioaddr = SDIO_BASE;
        host->buswidth = 4;
        host->dev_index = 0;
        host->bus_hz = 50000000;