MLK-14938-5 imx8: Add SoC level support
authorYe Li <ye.li@nxp.com>
Wed, 17 May 2017 07:00:43 +0000 (02:00 -0500)
committerJason Liu <jason.hui.liu@nxp.com>
Thu, 2 Nov 2017 18:36:49 +0000 (02:36 +0800)
Add cpu, power, and clocks functions for support i.MX8QM and i.MX8QXP SoCs.

Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@nxp.com>
Signed-off-by: Nitin Garg <nitin.garg@nxp.com>
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Signed-off-by: Adrian Alonso <adrian.alonso@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
arch/arm/cpu/armv8/imx8/Makefile
arch/arm/cpu/armv8/imx8/clock.c [new file with mode: 0644]
arch/arm/cpu/armv8/imx8/cpu.c [new file with mode: 0644]
arch/arm/include/asm/arch-imx/cpu.h
arch/arm/include/asm/arch-imx8/clock.h [new file with mode: 0644]
arch/arm/include/asm/arch-imx8/cpu.h [new file with mode: 0644]
arch/arm/include/asm/arch-imx8/i2c.h [new file with mode: 0644]
arch/arm/include/asm/arch-imx8/imx-regs.h [new file with mode: 0644]
arch/arm/include/asm/arch-imx8/sys_proto.h [new file with mode: 0644]
arch/arm/include/asm/imx-common/sys_proto.h

index 2ea6e94..6210dcd 100644 (file)
@@ -4,4 +4,6 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+obj-y += cpu.o
+obj-y += clock.o
 obj-y += fsl_mu_hal.o
diff --git a/arch/arm/cpu/armv8/imx8/clock.c b/arch/arm/cpu/armv8/imx8/clock.c
new file mode 100644 (file)
index 0000000..3351ed2
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/imx-common/sci/sci.h>
+#include <asm/arch/imx8-pins.h>
+#include <asm/arch/i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 get_lpuart_clk(void)
+{
+       return mxc_get_clock(MXC_UART_CLK);
+}
+
+static u32 get_arm_main_clk(void)
+{
+       sc_err_t err;
+       sc_pm_clock_rate_t clkrate;
+
+       err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle,
+                       SC_R_A53, SC_PM_CLK_CPU, &clkrate);
+       if (err != SC_ERR_NONE) {
+               printf("sc get ARM A53 clk failed! err=%d\n", err);
+               return 0;
+       }
+       return clkrate;
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+       sc_err_t err;
+       sc_pm_clock_rate_t clkrate;
+
+       switch (clk) {
+       case MXC_UART_CLK:
+               err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle,
+                               SC_R_UART_0, 2, &clkrate);
+               if (err != SC_ERR_NONE) {
+                       printf("sc get UART clk failed! err=%d\n", err);
+                       return 0;
+               }
+               return clkrate;
+       case MXC_ESDHC_CLK:
+               err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle,
+                               SC_R_SDHC_0, 2, &clkrate);
+               if (err != SC_ERR_NONE) {
+                       printf("sc get uSDHC1 clk failed! err=%d\n", err);
+                       return 0;
+               }
+               return clkrate;
+       case MXC_ESDHC2_CLK:
+               err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle,
+                               SC_R_SDHC_1, 2, &clkrate);
+               if (err != SC_ERR_NONE) {
+                       printf("sc get uSDHC2 clk failed! err=%d\n", err);
+                       return 0;
+               }
+               return clkrate;
+       case MXC_ESDHC3_CLK:
+               err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle,
+                               SC_R_SDHC_2, 2, &clkrate);
+               if (err != SC_ERR_NONE) {
+                       printf("sc get uSDHC3 clk failed! err=%d\n", err);
+                       return 0;
+               }
+               return clkrate;
+       case MXC_FEC_CLK:
+               err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle,
+                               SC_R_ENET_0, 2, &clkrate);
+               if (err != SC_ERR_NONE) {
+                       printf("sc get ENET clk failed! err=%d\n", err);
+                       return 0;
+               }
+               return clkrate;
+       case MXC_ARM_CLK:
+               return get_arm_main_clk();
+       default:
+               printf("Unsupported mxc_clock %d\n", clk);
+               break;
+       }
+
+       return 0;
+}
+
+u32 imx_get_fecclk(void)
+{
+       return mxc_get_clock(MXC_FEC_CLK);
+}
+
+int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
+{
+       sc_ipc_t ipc;
+       sc_err_t err;
+
+       if (i2c_num >= ARRAY_SIZE(imx_i2c_desc))
+               return -EINVAL;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       if (enable)
+               err = sc_pm_clock_enable(ipc,
+                       imx_i2c_desc[i2c_num].rsrc, 2, true, false);
+       else
+               err = sc_pm_clock_enable(ipc,
+                       imx_i2c_desc[i2c_num].rsrc, 2, false, false);
+
+       if (err != SC_ERR_NONE) {
+               printf("i2c clock error %d\n", err);
+               return -EPERM;
+       }
+
+       return 0;
+}
+
+u32 imx_get_i2cclk(unsigned i2c_num)
+{
+       sc_err_t err;
+       sc_ipc_t ipc;
+       u32 clock_rate;
+
+       if (i2c_num >= ARRAY_SIZE(imx_i2c_desc))
+               return 0;
+
+       ipc = gd->arch.ipc_channel_handle;
+       err = sc_pm_get_clock_rate(ipc, imx_i2c_desc[i2c_num].rsrc, 2,
+               &clock_rate);
+       if (err != SC_ERR_NONE)
+               return 0;
+
+       return clock_rate;
+}
+
+int set_clk_qspi(void)
+{
+       u32 err;
+       u32 rate = 40000000;
+       sc_ipc_t ipc;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       err = sc_pm_set_clock_rate(ipc, SC_R_QSPI_0, SC_PM_CLK_PER, &rate);
+       if (err != SC_ERR_NONE) {
+               printf("\nqspi set  clock rate (error = %d)\n", err);
+               return -EPERM;
+       }
+
+       err = sc_pm_clock_enable(ipc, SC_R_QSPI_0 , SC_PM_CLK_PER, true, false);
+       if (err != SC_ERR_NONE) {
+               printf("\nqspi enable clock enable (error = %d)\n", err);
+               return -EPERM;
+       }
+
+       return 0;
+}
+
+void enable_usboh3_clk(unsigned char enable)
+{
+       sc_err_t err;
+       sc_ipc_t ipc;
+       sc_rsrc_t usbs[] = {SC_R_USB_0, SC_R_USB_1, SC_R_USB_2};
+
+       int i;
+
+       ipc = gd->arch.ipc_channel_handle;
+       if (enable) {
+               for (i = 0; i < 2; i++) {
+                       /* The 24Mhz OTG PHY clock is pd linked, so it has been power up when pd is on */
+                       err = sc_pm_clock_enable(ipc, usbs[i], SC_PM_CLK_PHY, true, false);
+                       if (err != SC_ERR_NONE)
+                               printf("\nSC_R_USB_%d enable clock enable failed! (error = %d)\n", i, err);
+               }
+       } else {
+               for (i = 0; i < 2; i++) {
+                       err = sc_pm_clock_enable(ipc, usbs[i], SC_PM_CLK_PHY, false, false);
+                       if (err != SC_ERR_NONE)
+                               printf("\nSC_R_USB_%d enable clock disable failed! (error = %d)\n", i, err);
+               }
+       }
+
+       return;
+}
+
+void init_clk_usdhc(u32 index)
+{
+#ifdef CONFIG_IMX8QM
+       sc_rsrc_t usdhcs[] = {SC_R_SDHC_0, SC_R_SDHC_1, SC_R_SDHC_2};
+       u32 instances = 3;
+#else
+       sc_rsrc_t usdhcs[] = {SC_R_SDHC_0, SC_R_SDHC_1};
+       u32 instances = 2;
+#endif
+
+       sc_err_t err;
+       sc_ipc_t ipc;
+       sc_pm_clock_rate_t actual = 200000000;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       if (index >= instances)
+               return;
+
+       /* Power on the usdhc */
+       err = sc_pm_set_resource_power_mode(ipc, usdhcs[index],
+                               SC_PM_PW_MODE_ON);
+       if (err != SC_ERR_NONE) {
+               printf("SDHC_%d Power on failed! (error = %d)\n", index, err);
+               return;
+       }
+
+       err = sc_pm_set_clock_rate(ipc, usdhcs[index], 2, &actual);
+       if (err != SC_ERR_NONE) {
+               printf("SDHC_%d set clock failed! (error = %d)\n", index, err);
+               return;
+       }
+
+       if (actual != 200000000)
+               debug("Actual rate for SDHC_%d is %d\n", index, actual);
+
+       err = sc_pm_clock_enable(ipc, usdhcs[index], SC_PM_CLK_PER, true, false);
+       if (err != SC_ERR_NONE) {
+               printf("SDHC_%d per clk enable failed!\n", index);
+               return;
+       }
+}
diff --git a/arch/arm/cpu/armv8/imx8/cpu.c b/arch/arm/cpu/armv8/imx8/cpu.c
new file mode 100644 (file)
index 0000000..61c71d1
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/imx-common/sci/sci.h>
+#include <asm/arch/i2c.h>
+#include <asm/arch/clock.h>
+#include <asm/armv8/mmu.h>
+#include <elf.h>
+#include <asm/arch-imx/cpu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct mm_region imx8_mem_map[] = {
+       {
+               .virt = 0x0UL,
+               .phys = 0x0UL,
+               .size = 0x2000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_OUTER_SHARE
+       }, {
+               .virt = 0x2000000UL,
+               .phys = 0x2000000UL,
+               .size = 0x7E000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               .virt = 0x80000000UL,
+               .phys = 0x80000000UL,
+               .size = 0x80000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_OUTER_SHARE
+       }, {
+               .virt = 0x100000000UL,
+               .phys = 0x100000000UL,
+               .size = 0x700000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               .virt = 0x880000000UL,
+               .phys = 0x880000000UL,
+               .size = 0x780000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_OUTER_SHARE
+       }, {
+               /* List terminator */
+               0,
+       }
+};
+struct mm_region *mem_map = imx8_mem_map;
+
+u32 get_cpu_rev(void)
+{
+       sc_ipc_t ipcHndl;
+       uint32_t id = 0, rev = 0;
+       sc_err_t err;
+
+       ipcHndl = gd->arch.ipc_channel_handle;
+
+       err = sc_misc_get_control(ipcHndl, SC_R_SC_PID0, SC_C_ID, &id);
+       if (err != SC_ERR_NONE)
+               return 0;
+
+       rev = (id >> 5)  & 0xf;
+       id = (id & 0x1f) + MXC_SOC_IMX8;  /* Dummy ID for chip */
+
+       return (id << 12) | rev;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+const char *get_imx8_type(u32 imxtype)
+{
+       switch (imxtype) {
+       case MXC_CPU_IMX8QM:
+               return "8QM";   /* i.MX8 Quad MAX */
+       case MXC_CPU_IMX8QXP:
+               return "8QXP";  /* i.MX8 Quad XP */
+       case MXC_CPU_IMX8DX:
+               return "8DX";   /* i.MX8 Dual X */
+       default:
+               return "??";
+       }
+}
+
+const char *get_imx8_rev(u32 rev)
+{
+       switch (rev) {
+       case CHIP_REV_A:
+               return "A";
+       case CHIP_REV_B:
+               return "B";
+       default:
+               return "?";
+       }
+}
+
+int print_cpuinfo(void)
+{
+       u32 cpurev;
+       cpurev = get_cpu_rev();
+
+       printf("CPU:   Freescale i.MX%s rev%s at %d MHz\n",
+                       get_imx8_type((cpurev & 0xFF000) >> 12),
+                       get_imx8_rev((cpurev & 0xFFF)),
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+
+       return 0;
+}
+#endif
+
+int arch_cpu_init(void)
+{
+       sc_ipc_t ipcHndl = 0;
+       sc_err_t sciErr = 0;
+       gd->arch.ipc_channel_handle = 0;
+
+       /* Open IPC channel */
+       sciErr = sc_ipc_open(&ipcHndl, SC_IPC_CH);
+       if (sciErr != SC_ERR_NONE)
+               return -EPERM;
+
+       gd->arch.ipc_channel_handle = ipcHndl;
+
+       return 0;
+}
+
+u32 cpu_mask(void)
+{
+#ifdef CONFIG_IMX8QM
+       return 0x3f;
+#else
+       return 0xf;     /*For IMX8QXP*/
+#endif
+}
+
+#define CCI400_DVM_MESSAGE_REQ_EN      0x00000002
+#define CCI400_SNOOP_REQ_EN            0x00000001
+#define CHANGE_PENDING_BIT             (1 << 0)
+int imx8qm_wake_seconday_cores(void)
+{
+#ifdef CONFIG_ARMV8_MULTIENTRY
+       sc_ipc_t ipcHndl;
+       u64 *table = get_spin_tbl_addr();
+
+       /* Clear spin table so that secondary processors
+        * observe the correct value after waking up from wfe.
+        */
+       memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE);
+       flush_dcache_range((unsigned long)table,
+                          (unsigned long)table +
+                          (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE));
+
+       /* Open IPC channel */
+       if (sc_ipc_open(&ipcHndl, SC_IPC_CH)  != SC_ERR_NONE)
+               return -EIO;
+
+       __raw_writel(0xc, 0x52090000);
+       __raw_writel(1, 0x52090008);
+
+       /* IPC to pwr up and boot other cores */
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A53_1, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_2, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A53_2, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_3, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A53_3, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       /* Enable snoop and dvm msg requests for a53 port on CCI slave interface 3 */
+       __raw_writel(CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN, 0x52094000);
+
+       while (__raw_readl(0x5209000c) & CHANGE_PENDING_BIT)
+               ;
+
+       /* Pwr up cluster 1 and boot core 0*/
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72_0, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A72_0, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       /* IPC to pwr up and boot core 1 */
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A72_1, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       /* Enable snoop and dvm msg requests for a72 port on CCI slave interface 4 */
+       __raw_writel(CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN, 0x52095000);
+
+       while (__raw_readl(0x5209000c) & CHANGE_PENDING_BIT)
+               ;
+#endif
+       return 0;
+}
+
+int imx8qxp_wake_secondary_cores(void)
+{
+#ifdef CONFIG_ARMV8_MULTIENTRY
+       sc_ipc_t ipcHndl;
+       u64 *table = get_spin_tbl_addr();
+
+       /* Clear spin table so that secondary processors
+        * observe the correct value after waking up from wfe.
+        */
+       memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE);
+       flush_dcache_range((unsigned long)table,
+                          (unsigned long)table +
+                          (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE));
+
+       /* Open IPC channel */
+       if (sc_ipc_open(&ipcHndl, SC_IPC_CH)  != SC_ERR_NONE)
+               return -EIO;
+
+       /* IPC to pwr up and boot other cores */
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A35_1, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_2, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A35_2, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+       if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_3, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+               return -EIO;
+       if (sc_pm_cpu_start(ipcHndl, SC_R_A35_3, true, 0x80000000) != SC_ERR_NONE)
+               return -EIO;
+
+#endif
+       return 0;
+}
+
+int init_i2c_power(unsigned i2c_num)
+{
+       sc_ipc_t ipc;
+       sc_err_t err;
+       u32 i;
+
+       if (i2c_num >= ARRAY_SIZE(imx_i2c_desc))
+               return -EINVAL;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       for (i = 0; i < ARRAY_SIZE(i2c_parent_power_desc); i++) {
+               if (i2c_parent_power_desc[i].index == i2c_num) {
+                       err = sc_pm_set_resource_power_mode(ipc,
+                               i2c_parent_power_desc[i].rsrc, SC_PM_PW_MODE_ON);
+                       if (err != SC_ERR_NONE)
+                               return -EPERM;
+               }
+       }
+
+       /* power up i2c resource */
+       err = sc_pm_set_resource_power_mode(ipc,
+                       imx_i2c_desc[i2c_num].rsrc, SC_PM_PW_MODE_ON);
+       if (err != SC_ERR_NONE)
+               return -EPERM;
+
+       return 0;
+}
+
+#define FUSE_MAC0_WORD0 452
+#define FUSE_MAC0_WORD1 453
+#define FUSE_MAC1_WORD0 454
+#define FUSE_MAC1_WORD1 455 
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+       sc_err_t err;
+       sc_ipc_t ipc;
+       uint32_t val1 = 0, val2 = 0;
+       uint32_t word1, word2;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       if (dev_id == 0) {
+               word1 = FUSE_MAC0_WORD0;
+               word2 = FUSE_MAC0_WORD1;
+       } else {
+               word1 = FUSE_MAC1_WORD0;
+               word2 = FUSE_MAC1_WORD1;
+       }
+
+       err = sc_misc_otp_fuse_read(ipc, word1, &val1);
+       if (err != SC_ERR_NONE) {
+               printf("%s fuse %d read error: %d\n", __func__, word1, err);
+               return;
+       }
+
+       err = sc_misc_otp_fuse_read(ipc, word2, &val2);
+       if (err != SC_ERR_NONE) {
+               printf("%s fuse %d read error: %d\n", __func__, word2, err);
+               return;
+       }
+
+       mac[0] = val1;
+       mac[1] = val1 >> 8;
+       mac[2] = val1 >> 16;
+       mac[3] = val1 >> 24;
+       mac[4] = val2;
+       mac[5] = val2 >> 8;
+}
index b052406..e84621b 100644 (file)
 #define MXC_CPU_MX7S           0x71 /* dummy ID */
 #define MXC_CPU_MX7D           0x72
 #define MXC_CPU_MX7ULP         0x81 /* Temporally hard code */
+#define MXC_CPU_IMX8QM         0x91 /* dummy ID */
+#define MXC_CPU_IMX8QXP                0x92 /* dummy ID */
+#define MXC_CPU_IMX8DX         0x93 /* dummy ID */
 #define MXC_CPU_VF610          0xF6 /* dummy ID */
 
 #define MXC_SOC_MX6            0x60
 #define MXC_SOC_MX7            0x70
 #define MXC_SOC_MX7ULP         0x80 /* dummy */
+#define MXC_SOC_IMX8           0x90 /* dummy */
 
 #define CHIP_REV_1_0            0x10
 #define CHIP_REV_1_1            0x11
@@ -40,6 +44,9 @@
 #define CHIP_REV_2_5            0x25
 #define CHIP_REV_3_0            0x30
 
+#define CHIP_REV_A                             0x0
+#define CHIP_REV_B                             0x1
+
 #define BOARD_REV_1_0           0x0
 #define BOARD_REV_2_0           0x1
 #define BOARD_VER_OFFSET        0x8
diff --git a/arch/arm/include/asm/arch-imx8/clock.h b/arch/arm/include/asm/arch-imx8/clock.h
new file mode 100644 (file)
index 0000000..5d29522
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef __ASM_ARCH_CLOCK_H__
+#define __ASM_ARCH_CLOCK_H__
+
+/* Mainly for compatible to imx common code. */
+enum mxc_clock {
+       MXC_ARM_CLK = 0,
+       MXC_AHB_CLK,
+       MXC_IPG_CLK,
+       MXC_UART_CLK,
+       MXC_CSPI_CLK,
+       MXC_AXI_CLK,
+       MXC_DDR_CLK,
+       MXC_ESDHC_CLK,
+       MXC_ESDHC2_CLK,
+       MXC_ESDHC3_CLK,
+       MXC_I2C_CLK,
+       MXC_FEC_CLK,
+};
+
+u32 mxc_get_clock(enum mxc_clock clk);
+u32 get_lpuart_clk(void);
+int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
+u32 imx_get_i2cclk(unsigned i2c_num);
+void enable_usboh3_clk(unsigned char enable);
+int set_clk_qspi(void);
+u32 imx_get_fecclk(void);
+void init_clk_usdhc(u32 index);
+
+#endif /* __ASM_ARCH_CLOCK_H__ */
diff --git a/arch/arm/include/asm/arch-imx8/cpu.h b/arch/arm/include/asm/arch-imx8/cpu.h
new file mode 100644 (file)
index 0000000..b16f013
--- /dev/null
@@ -0,0 +1,7 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+u32 cpu_mask(void);
diff --git a/arch/arm/include/asm/arch-imx8/i2c.h b/arch/arm/include/asm/arch-imx8/i2c.h
new file mode 100644 (file)
index 0000000..665a41e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+#ifndef __ASM_ARCH_IMX8_I2C_H__
+#define __ASM_ARCH_IMX8_I2C_H__
+
+#include <asm/imx-common/sci/sci.h>
+
+struct imx_i2c_map {
+       int index;
+       sc_rsrc_t rsrc;
+};
+
+static struct imx_i2c_map imx_i2c_desc[] = {
+       {0, SC_R_I2C_0},
+       {1, SC_R_I2C_1},
+       {2, SC_R_I2C_2},
+       {3, SC_R_I2C_3},
+       {4, SC_R_I2C_4},
+       {5, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c0 */
+       {6, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c1 */
+       {7, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c0 */
+       {8, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c1 */
+       {9, SC_R_CSI_0_I2C_0},
+       {10, SC_R_CSI_1_I2C_0},
+       {11, SC_R_HDMI_I2C_0},
+       {12, SC_R_HDMI_RX_I2C_0},
+       {13, SC_R_MIPI_0_I2C_0},
+       {14, SC_R_MIPI_0_I2C_1},
+       {15, SC_R_MIPI_1_I2C_0},
+       {16, SC_R_MIPI_1_I2C_1},
+};
+
+/* The power should write in parent order*/
+static __attribute__((unused)) struct imx_i2c_map i2c_parent_power_desc[] = {
+       {5, SC_R_DC_0},
+       {5, SC_R_LVDS_0},
+       {6, SC_R_DC_0},
+       {6, SC_R_LVDS_0},
+       {7, SC_R_DC_1},
+       {7, SC_R_LVDS_1},
+       {8, SC_R_DC_1},
+       {8, SC_R_LVDS_1},
+       {13, SC_R_DC_0},
+       {13, SC_R_MIPI_0},
+       {14, SC_R_DC_0},
+       {14, SC_R_MIPI_0},
+       {15, SC_R_DC_1},
+       {15, SC_R_MIPI_1},
+       {16, SC_R_DC_1},
+       {16, SC_R_MIPI_1},
+};
+
+#endif /* __ASM_ARCH_IMX8_I2C_H__ */
diff --git a/arch/arm/include/asm/arch-imx8/imx-regs.h b/arch/arm/include/asm/arch-imx8/imx-regs.h
new file mode 100644 (file)
index 0000000..4166e95
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef __ASM_ARCH_IMX_REGS_H__
+#define __ASM_ARCH_IMX_REGS_H__
+
+#define MU_BASE_ADDR(id)       ((0x5D1B0000UL + (id*0x10000)))
+
+#define LPUART_BASE                    0x5A060000
+
+#define GPT1_BASE_ADDR         0x5D140000
+#define SCU_LPUART_BASE                0x33220000
+#define GPIO1_BASE_ADDR                0x5D080000
+#define GPIO2_BASE_ADDR                0x5D090000
+#define GPIO3_BASE_ADDR                0x5D0A0000
+#define GPIO4_BASE_ADDR                0x5D0B0000
+#define GPIO5_BASE_ADDR                0x5D0C0000
+#define GPIO6_BASE_ADDR                0x5D0D0000
+#define GPIO7_BASE_ADDR                0x5D0E0000
+#define GPIO8_BASE_ADDR                0x5D0F0000
+#define LPI2C1_BASE_ADDR       0x5A800000
+#define LPI2C2_BASE_ADDR       0x5A810000
+#define LPI2C3_BASE_ADDR       0x5A820000
+#define LPI2C4_BASE_ADDR       0x5A830000
+#define LPI2C5_BASE_ADDR       0x5A840000
+
+#ifdef CONFIG_LPUART
+#define LPUART_BASE            SCU_LPUART_BASE
+#endif
+
+#endif /* __ASM_ARCH_IMX_REGS_H__ */
diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h
new file mode 100644 (file)
index 0000000..a5dbb47
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm/imx-common/sys_proto.h>
+
+int init_qspi_power(void);
+int init_usb_power(void);
+int init_i2c_power(unsigned i2c_num);
index 3a6ebe2..a73be1e 100644 (file)
@@ -28,6 +28,7 @@
 
 #define is_mx6() (is_soc_type(MXC_SOC_MX6))
 #define is_mx7() (is_soc_type(MXC_SOC_MX7))
+#define is_imx8() (is_soc_type(MXC_SOC_IMX8))
 
 #define is_mx6dqp() (is_cpu_type(MXC_CPU_MX6QP) || is_cpu_type(MXC_CPU_MX6DP))
 #define is_mx6dq() (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
 
 #define is_mx7ulp() (is_cpu_type(MXC_CPU_MX7ULP))
 
+#define is_imx8qm() (is_cpu_type(MXC_CPU_IMX8QM))
+#define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))
+#define is_imx8dx() (is_cpu_type(MXC_CPU_IMX8DX))
+
 u32 get_nr_cpus(void);
 u32 get_cpu_rev(void);
 u32 get_cpu_speed_grade_hz(void);