int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; /* I2C 2 and 3 setup - I2C 3 hw mux with EIM */ if (is_mx6dq() || is_mx6dqp()) setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1); else setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1); /* I2C 3 Steer */ gpio_direction_output(IMX_GPIO_NR(5, 4), 1); SETUP_IOMUX_PADS(i2c3_pads); #ifndef CONFIG_SYS_FLASH_CFI if (is_mx6dq() || is_mx6dqp()) setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2); else setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2); #endif gpio_direction_output(IMX_GPIO_NR(1, 15), 1); SETUP_IOMUX_PADS(port_exp); #ifdef CONFIG_VIDEO_IPUV3 setup_display(); #endif #ifdef CONFIG_MTD_NOR_FLASH setup_iomux_eimnor(); #endif return 0; }
int setup_sata(void) { struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; int ret; if (!is_mx6dq() && !is_mx6dqp()) return 1; ret = enable_sata_clock(); if (ret) return ret; clrsetbits_le32(&iomuxc_regs->gpr[13], IOMUXC_GPR13_SATA_MASK, IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB |IOMUXC_GPR13_SATA_PHY_7_SATA2M |IOMUXC_GPR13_SATA_SPEED_3G |(3<<IOMUXC_GPR13_SATA_PHY_6_SHIFT) |IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED |IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16 |IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB |IOMUXC_GPR13_SATA_PHY_2_TX_1P104V |IOMUXC_GPR13_SATA_PHY_1_SLOW); return 0; }
static void spl_dram_init(void) { if (is_mx6dq()) ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table)); else if (is_mx6dqp()) ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table)); }
/* * This section requires the differentiation between iMX6 Sabre boards, but * for now, it will configure only for the mx6q variant. */ static void spl_dram_init(void) { struct mx6_ddr_sysinfo sysinfo = { /* width of data bus:0=16,1=32,2=64 */ .dsize = 2, /* config for full 4GB range so that get_mem_size() works */ .cs_density = 32, /* 32Gb per CS */ /* single chip select */ .ncs = 1, .cs1_mirror = 0, .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ .walat = 1, /* Write additional latency */ .ralat = 5, /* Read additional latency */ .mif3_mode = 3, /* Command prediction working mode */ .bi_on = 1, /* Bank interleaving enabled */ .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ .ddr_type = DDR_TYPE_DDR3, .refsel = 1, /* Refresh cycles at 32KHz */ .refr = 7, /* 8 refresh commands per refresh cycle */ }; if (is_mx6dqp()) { mx6dq_dram_iocfg(64, &mx6dqp_ddr_ioregs, &mx6_grp_ioregs); mx6_dram_cfg(&sysinfo, &mx6dqp_mmcd_calib, &mem_ddr); } else { mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); } } void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ arch_cpu_init(); ccgr_init(); gpr_init(); /* iomux and setup of i2c */ board_early_init_f(); /* setup GP timer */ timer_init(); /* UART clocks enabled and gd valid - init serial console */ preloader_console_init(); /* DDR initialization */ spl_dram_init(); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); }
static void setup_fec(void) { if (is_mx6dqp()) { /* * select ENET MAC0 TX clock from PLL */ imx_iomux_set_gpr_register(5, 9, 1, 1); enable_fec_anatop_clock(0, ENET_125MHZ); } setup_iomux_enet(); }
static inline int gpt_has_clk_source_osc(void) { #if defined(CONFIG_MX6) if (((is_mx6dq()) && (soc_rev() > CHIP_REV_1_0)) || is_mx6dqp() || is_mx6sdl() || is_mx6sx() || is_mx6ul()) return 1; return 0; #else return 0; #endif }
int board_fit_config_name_match(const char *name) { if (is_mx6dq()) { if (!strcmp(name, "imx6q-sabresd")) return 0; } else if (is_mx6dqp()) { if (!strcmp(name, "imx6qp-sabresd")) return 0; } else if (is_mx6dl()) { if (!strcmp(name, "imx6dl-sabresd")) return 0; } return -1; }
static void gpr_init(void) { struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; /* enable AXI cache for VDOA/VPU/IPU */ writel(0xF00000CF, &iomux->gpr[4]); if (is_mx6dqp()) { /* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */ writel(0x007F007F, &iomux->gpr[6]); writel(0x007F007F, &iomux->gpr[7]); } else { /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ writel(0x007F007F, &iomux->gpr[6]); writel(0x007F007F, &iomux->gpr[7]); } }
static void spl_dram_init(void) { if (is_mx6dqp()) { mx6dq_dram_iocfg(64, &mx6qp_ddr_ioregs, &mx6qp_grp_ioregs); spl_dram_init_imx6qp_lpddr3(); } else if (is_cpu_type(MXC_CPU_MX6SOLO)) { mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs); mx6_dram_cfg(&mem_s, &mx6s_512m_mmdc_calib, &h5tq2g63dfr); } else if (is_cpu_type(MXC_CPU_MX6DL)) { mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs); mx6_dram_cfg(&mem_dl, &mx6dl_1g_mmdc_calib, &h5tq2g63dfr); } else if (is_cpu_type(MXC_CPU_MX6Q)) { mx6dq_dram_iocfg(64, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs); mx6_dram_cfg(&mem_q, &mx6q_2g_mmdc_calib, &h5t04g63afr); } }
int board_late_init(void) { #ifdef CONFIG_CMD_BMODE add_board_boot_modes(board_boot_modes); #endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG setenv("board_name", "SABRESD"); if (is_mx6dqp()) setenv("board_rev", "MX6QP"); else if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) setenv("board_rev", "MX6Q"); else if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO)) setenv("board_rev", "MX6DL"); #endif return 0; }
int board_late_init(void) { #ifdef CONFIG_CMD_BMODE add_board_boot_modes(board_boot_modes); #endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG env_set("board_name", "SABREAUTO"); if (is_mx6dqp()) env_set("board_rev", "MX6QP"); else if (is_mx6dq()) env_set("board_rev", "MX6Q"); else if (is_mx6sdl()) env_set("board_rev", "MX6DL"); #endif return 0; }
int power_init_board(void) { struct pmic *p; unsigned int value; p = pfuze_common_init(I2C_PMIC); if (!p) return -ENODEV; if (is_mx6dqp()) { /* set SW2 staby volatage 0.975V*/ pmic_reg_read(p, PFUZE100_SW2STBY, &value); value &= ~0x3f; value |= 0x17; pmic_reg_write(p, PFUZE100_SW2STBY, value); } return pfuze_mode_init(p, APS_PFM); }
int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; #ifdef CONFIG_MXC_SPI setup_spi(); #endif if (is_mx6dq() || is_mx6dqp()) setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1); else setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1); #if defined(CONFIG_VIDEO_IPUV3) setup_display(); #endif #ifdef CONFIG_USB_EHCI_MX6 setup_usb(); #endif return 0; }
uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size) { uint32_t load_addr = 0; size_t bytes; ptrdiff_t ivt_offset = 0; int result = 0; ulong start; hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; hab_rvt_entry_t *hab_rvt_entry; hab_rvt_exit_t *hab_rvt_exit; hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; hab_rvt_entry = hab_rvt_entry_p; hab_rvt_exit = hab_rvt_exit_p; if (is_hab_enabled()) { printf("\nAuthenticate image from DDR location 0x%x...\n", ddr_start); hab_caam_clock_enable(1); if (hab_rvt_entry() == HAB_SUCCESS) { /* If not already aligned, Align to ALIGN_SIZE */ ivt_offset = (image_size + ALIGN_SIZE - 1) & ~(ALIGN_SIZE - 1); start = ddr_start; bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; #ifdef DEBUG printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ddr_start + ivt_offset); puts("Dumping IVT\n"); print_buffer(ddr_start + ivt_offset, (void *)(ddr_start + ivt_offset), 4, 0x8, 0); puts("Dumping CSF Header\n"); print_buffer(ddr_start + ivt_offset+IVT_SIZE, (void *)(ddr_start + ivt_offset+IVT_SIZE), 4, 0x10, 0); get_hab_status(); puts("\nCalling authenticate_image in ROM\n"); printf("\tivt_offset = 0x%x\n", ivt_offset); printf("\tstart = 0x%08lx\n", start); printf("\tbytes = 0x%x\n", bytes); #endif /* * If the MMU is enabled, we have to notify the ROM * code, or it won't flush the caches when needed. * This is done, by setting the "pu_irom_mmu_enabled" * word to 1. You can find its address by looking in * the ROM map. This is critical for * authenticate_image(). If MMU is enabled, without * setting this bit, authentication will fail and may * crash. */ /* Check MMU enabled */ if (get_cr() & CR_M) { if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) { /* * This won't work on Rev 1.0.0 of * i.MX6Q/D, since their ROM doesn't * do cache flushes. don't think any * exist, so we ignore them. */ if (!is_mx6dqp()) writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); } else if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO)) { writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); } else if (is_cpu_type(MXC_CPU_MX6SL)) { writel(1, MX6SL_PU_IROM_MMU_EN_VAR); } } load_addr = (uint32_t)hab_rvt_authenticate_image( HAB_CID_UBOOT, ivt_offset, (void **)&start, (size_t *)&bytes, NULL); if (hab_rvt_exit() != HAB_SUCCESS) { puts("hab exit function fail\n"); load_addr = 0; } } else { puts("hab entry function fail\n"); } hab_caam_clock_enable(0); get_hab_status(); } else { puts("hab fuse not enabled\n"); } if ((!is_hab_enabled()) || (load_addr != 0)) result = 1; return result; }
int power_init_board(void) { unsigned int reg; int ret; pfuze = pfuze_common_init(I2C_PMIC); if (!pfuze) return -ENODEV; if (is_mx6dqp()) ret = pfuze_mode_init(pfuze, APS_APS); else ret = pfuze_mode_init(pfuze, APS_PFM); if (ret < 0) return ret; /* Increase VGEN3 from 2.5 to 2.8V */ pmic_reg_read(pfuze, PFUZE100_VGEN3VOL, ®); reg &= ~LDO_VOL_MASK; reg |= LDOB_2_80V; pmic_reg_write(pfuze, PFUZE100_VGEN3VOL, reg); /* Increase VGEN5 from 2.8 to 3V */ pmic_reg_read(pfuze, PFUZE100_VGEN5VOL, ®); reg &= ~LDO_VOL_MASK; reg |= LDOB_3_00V; pmic_reg_write(pfuze, PFUZE100_VGEN5VOL, reg); if (is_mx6dqp()) { /* set SW1C staby volatage 1.075V*/ pmic_reg_read(pfuze, PFUZE100_SW1CSTBY, ®); reg &= ~0x3f; reg |= 0x1f; pmic_reg_write(pfuze, PFUZE100_SW1CSTBY, reg); /* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */ pmic_reg_read(pfuze, PFUZE100_SW1CCONF, ®); reg &= ~0xc0; reg |= 0x40; pmic_reg_write(pfuze, PFUZE100_SW1CCONF, reg); /* set SW2/VDDARM staby volatage 0.975V*/ pmic_reg_read(pfuze, PFUZE100_SW2STBY, ®); reg &= ~0x3f; reg |= 0x17; pmic_reg_write(pfuze, PFUZE100_SW2STBY, reg); /* set SW2/VDDARM step ramp up time to from 16us to 4us/25mV */ pmic_reg_read(pfuze, PFUZE100_SW2CONF, ®); reg &= ~0xc0; reg |= 0x40; pmic_reg_write(pfuze, PFUZE100_SW2CONF, reg); } else { /* set SW1AB staby volatage 0.975V*/ pmic_reg_read(pfuze, PFUZE100_SW1ABSTBY, ®); reg &= ~0x3f; reg |= 0x1b; pmic_reg_write(pfuze, PFUZE100_SW1ABSTBY, reg); /* set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ pmic_reg_read(pfuze, PFUZE100_SW1ABCONF, ®); reg &= ~0xc0; reg |= 0x40; pmic_reg_write(pfuze, PFUZE100_SW1ABCONF, reg); /* set SW1C staby volatage 0.975V*/ pmic_reg_read(pfuze, PFUZE100_SW1CSTBY, ®); reg &= ~0x3f; reg |= 0x1b; pmic_reg_write(pfuze, PFUZE100_SW1CSTBY, reg); /* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */ pmic_reg_read(pfuze, PFUZE100_SW1CCONF, ®); reg &= ~0xc0; reg |= 0x40; pmic_reg_write(pfuze, PFUZE100_SW1CCONF, reg); } return 0; }
void ldo_mode_set(int ldo_bypass) { unsigned int value; int is_400M; unsigned char vddarm; struct pmic *p = pfuze; if (!p) { printf("No PMIC found!\n"); return; } /* increase VDDARM/VDDSOC to support 1.2G chip */ if (check_1_2G()) { ldo_bypass = 0; /* ldo_enable on 1.2G chip */ printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n"); if (is_mx6dqp()) { /* increase VDDARM to 1.425V */ pmic_reg_read(p, PFUZE100_SW2VOL, &value); value &= ~0x3f; value |= 0x29; pmic_reg_write(p, PFUZE100_SW2VOL, value); } else { /* increase VDDARM to 1.425V */ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value); value &= ~0x3f; value |= 0x2d; pmic_reg_write(p, PFUZE100_SW1ABVOL, value); } /* increase VDDSOC to 1.425V */ pmic_reg_read(p, PFUZE100_SW1CVOL, &value); value &= ~0x3f; value |= 0x2d; pmic_reg_write(p, PFUZE100_SW1CVOL, value); } /* switch to ldo_bypass mode , boot on 800Mhz */ if (ldo_bypass) { prep_anatop_bypass(); if (is_mx6dqp()) { /* decrease VDDARM for 400Mhz DQP:1.1V*/ pmic_reg_read(p, PFUZE100_SW2VOL, &value); value &= ~0x3f; value |= 0x1c; pmic_reg_write(p, PFUZE100_SW2VOL, value); } else { /* decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V */ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value); value &= ~0x3f; #if defined(CONFIG_MX6DL) value |= 0x27; #else value |= 0x20; #endif pmic_reg_write(p, PFUZE100_SW1ABVOL, value); } /* increase VDDSOC to 1.3V */ pmic_reg_read(p, PFUZE100_SW1CVOL, &value); value &= ~0x3f; value |= 0x28; pmic_reg_write(p, PFUZE100_SW1CVOL, value); /* * MX6Q/DQP: * VDDARM:1.15V@800M; VDDSOC:1.175V@800M * VDDARM:0.975V@400M; VDDSOC:1.175V@400M * MX6DL: * VDDARM:1.175V@800M; VDDSOC:1.175V@800M * VDDARM:1.075V@400M; VDDSOC:1.175V@400M */ is_400M = set_anatop_bypass(2); if (is_mx6dqp()) { pmic_reg_read(p, PFUZE100_SW2VOL, &value); value &= ~0x3f; if (is_400M) value |= 0x17; else value |= 0x1e; pmic_reg_write(p, PFUZE100_SW2VOL, value); } if (is_400M) #if defined(CONFIG_MX6DL) vddarm = 0x1f; #else vddarm = 0x1b; #endif else #if defined(CONFIG_MX6DL) vddarm = 0x23; #else vddarm = 0x22; #endif pmic_reg_read(p, PFUZE100_SW1ABVOL, &value); value &= ~0x3f; value |= vddarm; pmic_reg_write(p, PFUZE100_SW1ABVOL, value); /* decrease VDDSOC to 1.175V */ pmic_reg_read(p, PFUZE100_SW1CVOL, &value); value &= ~0x3f; value |= 0x23; pmic_reg_write(p, PFUZE100_SW1CVOL, value); finish_anatop_bypass(); printf("switch to ldo_bypass mode!\n"); }