1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2020 PHYTEC Messtechnik GmbH 4 * Author: Teresa Remmet <t.remmet@phytec.de> 5 */ 6 7#include <common.h> 8#include <asm/arch/clock.h> 9#include <asm/arch/ddr.h> 10#include <asm/arch/imx8mp_pins.h> 11#include <asm/arch/sys_proto.h> 12#include <asm/global_data.h> 13#include <asm/mach-imx/boot_mode.h> 14#include <asm/mach-imx/gpio.h> 15#include <asm/mach-imx/mxc_i2c.h> 16#include <asm/mach-imx/iomux-v3.h> 17#include <hang.h> 18#include <init.h> 19#include <log.h> 20#include <power/pmic.h> 21#include <power/pca9450.h> 22#include <spl.h> 23 24#include "../common/imx8m_som_detection.h" 25 26DECLARE_GLOBAL_DATA_PTR; 27 28#define EEPROM_ADDR 0x51 29#define EEPROM_ADDR_FALLBACK 0x59 30 31int spl_board_boot_device(enum boot_device boot_dev_spl) 32{ 33 return BOOT_DEVICE_BOOTROM; 34} 35 36void spl_dram_init(void) 37{ 38 int ret; 39 40 ret = phytec_eeprom_data_setup_fallback(NULL, 0, EEPROM_ADDR, 41 EEPROM_ADDR_FALLBACK); 42 if (ret) 43 goto out; 44 45 ret = phytec_imx8m_detect(NULL); 46 if (!ret) 47 phytec_print_som_info(NULL); 48 49 u8 rev = phytec_get_rev(NULL); 50 u8 somtype = phytec_get_som_type(NULL); 51 52 if (rev != PHYTEC_EEPROM_INVAL && (rev >= 3 || (somtype == SOM_TYPE_PCL && rev >= 1))) { 53 dram_timing.ddrc_cfg[3].val = 0x1323; 54 dram_timing.ddrc_cfg[4].val = 0x1e84800; 55 dram_timing.ddrc_cfg[5].val = 0x7a0118; 56 dram_timing.ddrc_cfg[8].val = 0xc00307a3; 57 dram_timing.ddrc_cfg[9].val = 0xc50000; 58 dram_timing.ddrc_cfg[10].val = 0xf4003f; 59 dram_timing.ddrc_cfg[11].val = 0xf30000; 60 dram_timing.ddrc_cfg[14].val = 0x2028222a; 61 dram_timing.ddrc_cfg[15].val = 0x8083f; 62 dram_timing.ddrc_cfg[16].val = 0xe0e000; 63 dram_timing.ddrc_cfg[17].val = 0x12040a12; 64 dram_timing.ddrc_cfg[18].val = 0x2050f0f; 65 dram_timing.ddrc_cfg[19].val = 0x1010009; 66 dram_timing.ddrc_cfg[20].val = 0x502; 67 dram_timing.ddrc_cfg[21].val = 0x20800; 68 dram_timing.ddrc_cfg[22].val = 0xe100002; 69 dram_timing.ddrc_cfg[23].val = 0x120; 70 dram_timing.ddrc_cfg[24].val = 0xc80064; 71 dram_timing.ddrc_cfg[25].val = 0x3e8001e; 72 dram_timing.ddrc_cfg[26].val = 0x3207a12; 73 dram_timing.ddrc_cfg[28].val = 0x4a3820e; 74 dram_timing.ddrc_cfg[30].val = 0x230e; 75 dram_timing.ddrc_cfg[37].val = 0x799; 76 dram_timing.ddrc_cfg[38].val = 0x9141d1c; 77 dram_timing.ddrc_cfg[74].val = 0x302; 78 dram_timing.ddrc_cfg[83].val = 0x599; 79 dram_timing.ddrc_cfg[99].val = 0x302; 80 dram_timing.ddrc_cfg[108].val = 0x599; 81 dram_timing.ddrphy_cfg[66].val = 0x18; 82 dram_timing.ddrphy_cfg[75].val = 0x1e3; 83 dram_timing.ddrphy_cfg[77].val = 0x1e3; 84 dram_timing.ddrphy_cfg[79].val = 0x1e3; 85 dram_timing.ddrphy_cfg[145].val = 0x3e8; 86 dram_timing.fsp_msg[0].drate = 4000; 87 dram_timing.fsp_msg[0].fsp_cfg[1].val = 0xfa0; 88 dram_timing.fsp_msg[0].fsp_cfg[10].val = 0x3ff4; 89 dram_timing.fsp_msg[0].fsp_cfg[11].val = 0xf3; 90 dram_timing.fsp_msg[0].fsp_cfg[15].val = 0x3ff4; 91 dram_timing.fsp_msg[0].fsp_cfg[16].val = 0xf3; 92 dram_timing.fsp_msg[0].fsp_cfg[22].val = 0xf400; 93 dram_timing.fsp_msg[0].fsp_cfg[23].val = 0xf33f; 94 dram_timing.fsp_msg[0].fsp_cfg[28].val = 0xf400; 95 dram_timing.fsp_msg[0].fsp_cfg[29].val = 0xf33f; 96 dram_timing.fsp_msg[3].drate = 4000; 97 dram_timing.fsp_msg[3].fsp_cfg[1].val = 0xfa0; 98 dram_timing.fsp_msg[3].fsp_cfg[11].val = 0x3ff4; 99 dram_timing.fsp_msg[3].fsp_cfg[12].val = 0xf3; 100 dram_timing.fsp_msg[3].fsp_cfg[16].val = 0x3ff4; 101 dram_timing.fsp_msg[3].fsp_cfg[17].val = 0xf3; 102 dram_timing.fsp_msg[3].fsp_cfg[23].val = 0xf400; 103 dram_timing.fsp_msg[3].fsp_cfg[24].val = 0xf33f; 104 dram_timing.fsp_msg[3].fsp_cfg[29].val = 0xf400; 105 dram_timing.fsp_msg[3].fsp_cfg[30].val = 0xf33f; 106 dram_timing.ddrphy_pie[480].val = 0x465; 107 dram_timing.ddrphy_pie[481].val = 0xfa; 108 dram_timing.ddrphy_pie[482].val = 0x9c4; 109 dram_timing.fsp_table[0] = 4000; 110 } 111 112out: 113 ddr_init(&dram_timing); 114} 115 116#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PE) 117#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) 118struct i2c_pads_info i2c_pad_info1 = { 119 .scl = { 120 .i2c_mode = MX8MP_PAD_I2C1_SCL__I2C1_SCL | PC, 121 .gpio_mode = MX8MP_PAD_I2C1_SCL__GPIO5_IO14 | PC, 122 .gp = IMX_GPIO_NR(5, 14), 123 }, 124 .sda = { 125 .i2c_mode = MX8MP_PAD_I2C1_SDA__I2C1_SDA | PC, 126 .gpio_mode = MX8MP_PAD_I2C1_SDA__GPIO5_IO15 | PC, 127 .gp = IMX_GPIO_NR(5, 15), 128 }, 129}; 130 131int power_init_board(void) 132{ 133 struct pmic *p; 134 int ret; 135 136 ret = power_pca9450_init(0, 0x25); 137 if (ret) 138 printf("power init failed"); 139 p = pmic_get("PCA9450"); 140 pmic_probe(p); 141 142 /* BUCKxOUT_DVS0/1 control BUCK123 output */ 143 pmic_reg_write(p, PCA9450_BUCK123_DVS, 0x29); 144 145 /* Increase VDD_SOC and VDD_ARM to OD voltage 0.95V */ 146 pmic_reg_write(p, PCA9450_BUCK1OUT_DVS0, 0x1C); 147 pmic_reg_write(p, PCA9450_BUCK2OUT_DVS0, 0x1C); 148 149 /* Set BUCK1 DVS1 to suspend controlled through PMIC_STBY_REQ */ 150 pmic_reg_write(p, PCA9450_BUCK1OUT_DVS1, 0x14); 151 pmic_reg_write(p, PCA9450_BUCK1CTRL, 0x59); 152 153 /* Set WDOG_B_CFG to cold reset */ 154 pmic_reg_write(p, PCA9450_RESET_CTRL, 0xA1); 155 156 return 0; 157} 158 159void spl_board_init(void) 160{ 161 /* Set GIC clock to 500Mhz for OD VDD_SOC. */ 162 clock_enable(CCGR_GIC, 0); 163 clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5)); 164 clock_enable(CCGR_GIC, 1); 165} 166 167int board_fit_config_name_match(const char *name) 168{ 169 return 0; 170} 171 172void board_init_f(ulong dummy) 173{ 174 int ret; 175 176 arch_cpu_init(); 177 178 init_uart_clk(0); 179 180 ret = spl_early_init(); 181 if (ret) { 182 debug("spl_early_init() failed: %d\n", ret); 183 hang(); 184 } 185 186 preloader_console_init(); 187 188 enable_tzc380(); 189 190 setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); 191 192 power_init_board(); 193 194 /* DDR initialization */ 195 spl_dram_init(); 196} 197