Commit c5752f73a53a8396aae1efa51c5af14b21210b3a

Authored by Adrian Alonso
Committed by Stefano Babic
1 parent 7bebc4b04e

imx: imx7d: Add SoC system support

Add imx7d basic SoC system support
Misc arch dependent functions for system bring up

Signed-off-by: Adrian Alonso <aalonso@freescale.com>
Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Ye.Li <B37916@freescale.com>

Showing 3 changed files with 292 additions and 0 deletions Side-by-side Diff

arch/arm/cpu/armv7/mx7/soc.c
  1 +/*
  2 + * Copyright (C) 2015 Freescale Semiconductor, Inc.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#include <common.h>
  8 +#include <asm/io.h>
  9 +#include <asm/arch/imx-regs.h>
  10 +#include <asm/arch/clock.h>
  11 +#include <asm/arch/sys_proto.h>
  12 +#include <asm/imx-common/boot_mode.h>
  13 +#include <asm/imx-common/dma.h>
  14 +#include <asm/arch/crm_regs.h>
  15 +#include <dm.h>
  16 +#include <imx_thermal.h>
  17 +
  18 +struct src *src_reg = (struct src *)SRC_BASE_ADDR;
  19 +
  20 +#if defined(CONFIG_IMX_THERMAL)
  21 +static const struct imx_thermal_plat imx7_thermal_plat = {
  22 + .regs = (void *)ANATOP_BASE_ADDR,
  23 + .fuse_bank = 3,
  24 + .fuse_word = 3,
  25 +};
  26 +
  27 +U_BOOT_DEVICE(imx7_thermal) = {
  28 + .name = "imx_thermal",
  29 + .platdata = &imx7_thermal_plat,
  30 +};
  31 +#endif
  32 +
  33 +/*
  34 + * OCOTP_TESTER3[9:8] (see Fusemap Description Table offset 0x440)
  35 + * defines a 2-bit SPEED_GRADING
  36 + */
  37 +#define OCOTP_TESTER3_SPEED_SHIFT 8
  38 +#define OCOTP_TESTER3_SPEED_800MHZ 0
  39 +#define OCOTP_TESTER3_SPEED_850MHZ 1
  40 +#define OCOTP_TESTER3_SPEED_1GHZ 2
  41 +
  42 +u32 get_cpu_speed_grade_hz(void)
  43 +{
  44 + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  45 + struct fuse_bank *bank = &ocotp->bank[1];
  46 + struct fuse_bank1_regs *fuse =
  47 + (struct fuse_bank1_regs *)bank->fuse_regs;
  48 + uint32_t val;
  49 +
  50 + val = readl(&fuse->tester3);
  51 + val >>= OCOTP_TESTER3_SPEED_SHIFT;
  52 + val &= 0x3;
  53 +
  54 + switch(val) {
  55 + case OCOTP_TESTER3_SPEED_800MHZ:
  56 + return 792000000;
  57 + case OCOTP_TESTER3_SPEED_850MHZ:
  58 + return 852000000;
  59 + case OCOTP_TESTER3_SPEED_1GHZ:
  60 + return 996000000;
  61 + }
  62 + return 0;
  63 +}
  64 +
  65 +/*
  66 + * OCOTP_TESTER3[7:6] (see Fusemap Description Table offset 0x440)
  67 + * defines a 2-bit SPEED_GRADING
  68 + */
  69 +#define OCOTP_TESTER3_TEMP_SHIFT 6
  70 +
  71 +u32 get_cpu_temp_grade(int *minc, int *maxc)
  72 +{
  73 + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  74 + struct fuse_bank *bank = &ocotp->bank[1];
  75 + struct fuse_bank1_regs *fuse =
  76 + (struct fuse_bank1_regs *)bank->fuse_regs;
  77 + uint32_t val;
  78 +
  79 + val = readl(&fuse->tester3);
  80 + val >>= OCOTP_TESTER3_TEMP_SHIFT;
  81 + val &= 0x3;
  82 +
  83 + if (minc && maxc) {
  84 + if ( val == TEMP_AUTOMOTIVE) {
  85 + *minc = -40;
  86 + *maxc = 125;
  87 + } else if (val == TEMP_INDUSTRIAL) {
  88 + *minc = -40;
  89 + *maxc = 105;
  90 + } else if (val == TEMP_EXTCOMMERCIAL) {
  91 + *minc = -20;
  92 + *maxc = 105;
  93 + } else {
  94 + *minc = 0;
  95 + *maxc = 95;
  96 + }
  97 + }
  98 + return val;
  99 +}
  100 +
  101 +u32 get_cpu_rev(void)
  102 +{
  103 + struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *)
  104 + ANATOP_BASE_ADDR;
  105 + u32 reg = readl(&ccm_anatop->digprog);
  106 + u32 type = (reg >> 16) & 0xff;
  107 +
  108 + reg &= 0xff;
  109 + return (type << 12) | reg;
  110 +}
  111 +
  112 +#ifdef CONFIG_REVISION_TAG
  113 +u32 __weak get_board_rev(void)
  114 +{
  115 + return get_cpu_rev();
  116 +}
  117 +#endif
  118 +
  119 +int arch_cpu_init(void)
  120 +{
  121 + init_aips();
  122 +
  123 + /* Disable PDE bit of WMCR register */
  124 + imx_set_wdog_powerdown(false);
  125 +
  126 +#ifdef CONFIG_APBH_DMA
  127 + /* Start APBH DMA */
  128 + mxs_dma_init();
  129 +#endif
  130 +
  131 + return 0;
  132 +}
  133 +
  134 +#ifdef CONFIG_SERIAL_TAG
  135 +void get_board_serial(struct tag_serialnr *serialnr)
  136 +{
  137 + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  138 + struct fuse_bank *bank = &ocotp->bank[0];
  139 + struct fuse_bank0_regs *fuse =
  140 + (struct fuse_bank0_regs *)bank->fuse_regs;
  141 +
  142 + serialnr->low = fuse->tester0;
  143 + serialnr->high = fuse->tester1;
  144 +}
  145 +#endif
  146 +
  147 +#if defined(CONFIG_FEC_MXC)
  148 +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
  149 +{
  150 + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  151 + struct fuse_bank *bank = &ocotp->bank[9];
  152 + struct fuse_bank9_regs *fuse =
  153 + (struct fuse_bank9_regs *)bank->fuse_regs;
  154 +
  155 + if (0 == dev_id) {
  156 + u32 value = readl(&fuse->mac_addr1);
  157 + mac[0] = (value >> 8);
  158 + mac[1] = value;
  159 +
  160 + value = readl(&fuse->mac_addr0);
  161 + mac[2] = value >> 24;
  162 + mac[3] = value >> 16;
  163 + mac[4] = value >> 8;
  164 + mac[5] = value;
  165 + } else {
  166 + u32 value = readl(&fuse->mac_addr2);
  167 + mac[0] = value >> 24;
  168 + mac[1] = value >> 16;
  169 + mac[2] = value >> 8;
  170 + mac[3] = value;
  171 +
  172 + value = readl(&fuse->mac_addr1);
  173 + mac[4] = value >> 24;
  174 + mac[5] = value >> 16;
  175 + }
  176 +}
  177 +#endif
  178 +
  179 +void set_wdog_reset(struct wdog_regs *wdog)
  180 +{
  181 + u32 reg = readw(&wdog->wcr);
  182 + /*
  183 + * Output WDOG_B signal to reset external pmic or POR_B decided by
  184 + * the board desgin. Without external reset, the peripherals/DDR/
  185 + * PMIC are not reset, that may cause system working abnormal.
  186 + */
  187 + reg = readw(&wdog->wcr);
  188 + reg |= 1 << 3;
  189 + /*
  190 + * WDZST bit is write-once only bit. Align this bit in kernel,
  191 + * otherwise kernel code will have no chance to set this bit.
  192 + */
  193 + reg |= 1 << 0;
  194 + writew(reg, &wdog->wcr);
  195 +}
  196 +
  197 +/*
  198 + * cfg_val will be used for
  199 + * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
  200 + * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
  201 + * to SBMR1, which will determine the boot device.
  202 + */
  203 +const struct boot_mode soc_boot_modes[] = {
  204 + {"ecspi1:0", MAKE_CFGVAL(0x00, 0x60, 0x00, 0x00)},
  205 + {"ecspi1:1", MAKE_CFGVAL(0x40, 0x62, 0x00, 0x00)},
  206 + {"ecspi1:2", MAKE_CFGVAL(0x80, 0x64, 0x00, 0x00)},
  207 + {"ecspi1:3", MAKE_CFGVAL(0xc0, 0x66, 0x00, 0x00)},
  208 +
  209 + {"weim", MAKE_CFGVAL(0x00, 0x50, 0x00, 0x00)},
  210 + {"qspi1", MAKE_CFGVAL(0x10, 0x40, 0x00, 0x00)},
  211 + /* 4 bit bus width */
  212 + {"usdhc1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)},
  213 + {"usdhc2", MAKE_CFGVAL(0x10, 0x14, 0x00, 0x00)},
  214 + {"usdhc3", MAKE_CFGVAL(0x10, 0x18, 0x00, 0x00)},
  215 + {"mmc1", MAKE_CFGVAL(0x10, 0x20, 0x00, 0x00)},
  216 + {"mmc2", MAKE_CFGVAL(0x10, 0x24, 0x00, 0x00)},
  217 + {"mmc3", MAKE_CFGVAL(0x10, 0x28, 0x00, 0x00)},
  218 + {NULL, 0},
  219 +};
  220 +
  221 +enum boot_device get_boot_device(void)
  222 +{
  223 + struct bootrom_sw_info **p =
  224 + (struct bootrom_sw_info **)ROM_SW_INFO_ADDR;
  225 +
  226 + enum boot_device boot_dev = SD1_BOOT;
  227 + u8 boot_type = (*p)->boot_dev_type;
  228 + u8 boot_instance = (*p)->boot_dev_instance;
  229 +
  230 + switch (boot_type) {
  231 + case BOOT_TYPE_SD:
  232 + boot_dev = boot_instance + SD1_BOOT;
  233 + break;
  234 + case BOOT_TYPE_MMC:
  235 + boot_dev = boot_instance + MMC1_BOOT;
  236 + break;
  237 + case BOOT_TYPE_NAND:
  238 + boot_dev = NAND_BOOT;
  239 + break;
  240 + case BOOT_TYPE_QSPI:
  241 + boot_dev = QSPI_BOOT;
  242 + break;
  243 + case BOOT_TYPE_WEIM:
  244 + boot_dev = WEIM_NOR_BOOT;
  245 + break;
  246 + case BOOT_TYPE_SPINOR:
  247 + boot_dev = SPI_NOR_BOOT;
  248 + break;
  249 + default:
  250 + break;
  251 + }
  252 +
  253 + return boot_dev;
  254 +}
  255 +
  256 +void s_init(void)
  257 +{
  258 +#if !defined CONFIG_SPL_BUILD
  259 + /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
  260 + asm volatile(
  261 + "mrc p15, 0, r0, c1, c0, 1\n"
  262 + "orr r0, r0, #1 << 6\n"
  263 + "mcr p15, 0, r0, c1, c0, 1\n");
  264 +#endif
  265 + /* clock configuration. */
  266 + clock_init();
  267 +
  268 + return;
  269 +}
arch/arm/include/asm/arch-imx/cpu.h
... ... @@ -21,9 +21,11 @@
21 21 #define MXC_CPU_MX6D 0x67
22 22 #define MXC_CPU_MX6DP 0x68
23 23 #define MXC_CPU_MX6QP 0x69
  24 +#define MXC_CPU_MX7D 0x72
24 25 #define MXC_CPU_VF610 0xF6 /* dummy ID */
25 26  
26 27 #define MXC_SOC_MX6 0x60
  28 +#define MXC_SOC_MX7 0x70
27 29  
28 30 #define CS0_128 0
29 31 #define CS0_64M_CS1_64M 1
arch/arm/include/asm/imx-common/boot_mode.h
... ... @@ -9,6 +9,27 @@
9 9 #define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \
10 10 ((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1)
11 11  
  12 +enum boot_device {
  13 + WEIM_NOR_BOOT,
  14 + ONE_NAND_BOOT,
  15 + PATA_BOOT,
  16 + SATA_BOOT,
  17 + I2C_BOOT,
  18 + SPI_NOR_BOOT,
  19 + SD1_BOOT,
  20 + SD2_BOOT,
  21 + SD3_BOOT,
  22 + SD4_BOOT,
  23 + MMC1_BOOT,
  24 + MMC2_BOOT,
  25 + MMC3_BOOT,
  26 + MMC4_BOOT,
  27 + NAND_BOOT,
  28 + QSPI_BOOT,
  29 + UNKNOWN_BOOT,
  30 + BOOT_DEV_NUM = UNKNOWN_BOOT,
  31 +};
  32 +
12 33 struct boot_mode {
13 34 const char *name;
14 35 unsigned cfg_val;