From: Alexey Brodkin Date: Tue, 27 Nov 2018 06:46:59 +0000 (+0300) Subject: arc: emsdp: Read real CPU clock value from hardware X-Git-Tag: v2019.01-rc1~13^2~2 X-Git-Url: https://git.librecmc.org/?p=oweals%2Fu-boot.git;a=commitdiff_plain;h=4e86c7e3cd21fdab46416284665dbb589f110b94 arc: emsdp: Read real CPU clock value from hardware 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 --- diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c index b5ec7f17ec..5ab4435374 100644 --- a/board/synopsys/emsdp/emsdp.c +++ b/board/synopsys/emsdp/emsdp.c @@ -7,10 +7,46 @@ #include #include +#include + 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;