Merge tag 'rpi-next-2020.07' of https://gitlab.denx.de/u-boot/custodians/u-boot-raspb...
[oweals/u-boot.git] / board / synopsys / emsdp / emsdp.c
index b5ec7f17ec1b35c4f6a79ec639bf9497a58da6c3..c09ed8cff826d616febb252bc2cde7b6fd06c81d 100644 (file)
  */
 
 #include <common.h>
+#include <cpu_func.h>
 #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 board_mmc_init(bd_t *bis)
+int mach_cpu_init(void)
 {
-       struct dwmci_host *host = NULL;
+       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));
 
-       host = malloc(sizeof(struct dwmci_host));
-       if (!host) {
-               printf("dwmci_host malloc fail!\n");
-               return 1;
-       }
+       /* Amount of reference 100 MHz clocks */
+       rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
+              CGU_ARC_FMEAS_ARC_CNT_MASK);
 
-       memset(host, 0, sizeof(struct dwmci_host));
-       host->name = "Synopsys Mobile storage";
-       host->ioaddr = (void *)SDIO_BASE;
-       host->buswidth = 4;
-       host->dev_index = 0;
-       host->bus_hz = 50000000;
+       /* Amount of CPU clocks */
+       fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
+              CGU_ARC_FMEAS_ARC_CNT_MASK);
 
-       add_dwmci(host, host->bus_hz / 2, 400000);
+       gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
 
        return 0;
 }
 
-int board_mmc_getcd(struct mmc *mmc)
+int board_early_init_r(void)
 {
-       struct dwmci_host *host = mmc->priv;
+#define EMSDP_PSRAM_BASE               0xf2001000
+#define PSRAM_FLASH_CONFIG_REG_0       (void *)(EMSDP_PSRAM_BASE + 0x10)
+#define PSRAM_FLASH_CONFIG_REG_1       (void *)(EMSDP_PSRAM_BASE + 0x14)
+#define CRE_ENABLE                     BIT(31)
+#define CRE_DRIVE_CMD                  BIT(6)
+
+#define PSRAM_RCR_DPD                  BIT(1)
+#define PSRAM_RCR_PAGE_MODE            BIT(7)
+
+/*
+ * PSRAM_FLASH_CONFIG_REG_x[30:15] to the address lines[16:1] of flash,
+ * thus "<< 1".
+ */
+#define PSRAM_RCR_SETUP                ((PSRAM_RCR_DPD | PSRAM_RCR_PAGE_MODE) << 1)
+
+       // Switch PSRAM controller to command mode
+       writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_0);
+       // Program Refresh Configuration Register (RCR) for BANK0
+       writew(0, (void *)(0x10000000 + PSRAM_RCR_SETUP));
+       // Switch PSRAM controller back to memory mode
+       writel(0, PSRAM_FLASH_CONFIG_REG_0);
 
-       return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+
+       // Switch PSRAM controller to command mode
+       writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_1);
+       // Program Refresh Configuration Register (RCR) for BANK1
+       writew(0, (void *)(0x10800000 + PSRAM_RCR_SETUP));
+       // Switch PSRAM controller back to memory mode
+       writel(0, PSRAM_FLASH_CONFIG_REG_1);
+
+       printf("PSRAM initialized.\n");
+
+       return 0;
 }
 
 #define CREG_BASE              0xF0001000
-#define CREG_BOOT_OFFSET       0
-#define CREG_BOOT_WP_OFFSET    8
+#define CREG_BOOT              (void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_SW_RESET       (void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_VERSION                (void *)(CREG_BASE + 0x0FF8)
 
-#define CGU_BASE               0xF0000000
-#define CGU_IP_SW_RESET                0x0FF0
+/* Bits in CREG_BOOT register */
+#define CREG_BOOT_WP_BIT       BIT(8)
 
 void reset_cpu(ulong addr)
 {
-       writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET));
+       writel(1, CREG_IP_SW_RESET);
        while (1)
                ; /* loop forever till reset */
 }
 
 static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-       u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+       u32 creg_boot = readl(CREG_BOOT);
 
        if (!strcmp(argv[1], "unlock"))
-               creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET);
+               creg_boot &= ~CREG_BOOT_WP_BIT;
        else if (!strcmp(argv[1], "lock"))
-               creg_boot |= BIT(CREG_BOOT_WP_OFFSET);
+               creg_boot |= CREG_BOOT_WP_BIT;
        else
                return CMD_RET_USAGE;
 
-       writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+       writel(creg_boot, CREG_BOOT);
 
        return CMD_RET_SUCCESS;
 }
@@ -97,3 +143,12 @@ U_BOOT_CMD(
        "rom unlock - Unlock non-volatile memory for writing\n"
        "emsdp rom lock - Lock non-volatile memory to prevent writing\n"
 );
+
+int checkboard(void)
+{
+       int version = readl(CREG_IP_VERSION);
+
+       printf("Board: ARC EM Software Development Platform v%d.%d\n",
+              (version >> 16) & 0xff, version & 0xff);
+       return 0;
+};