1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2022 Marek Vasut <marex@denx.de> 4 */ 5 6#include <common.h> 7#include <asm-generic/gpio.h> 8#include <asm-generic/sections.h> 9#include <asm/arch/clock.h> 10#include <asm/arch/ddr.h> 11#include <asm/arch/sys_proto.h> 12#include <asm/io.h> 13#include <asm/mach-imx/boot_mode.h> 14#include <asm/mach-imx/iomux-v3.h> 15#include <dm/uclass.h> 16#include <hang.h> 17#include <i2c_eeprom.h> 18#include <image.h> 19#include <init.h> 20#include <net.h> 21#include <spl.h> 22 23#include <dm/uclass.h> 24#include <dm/device.h> 25#include <dm/uclass-internal.h> 26#include <dm/device-internal.h> 27 28DECLARE_GLOBAL_DATA_PTR; 29 30#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) 31 32#define DDRC_ECCCFG0_ECC_MODE_MASK 0x7 33 34u8 dmo_get_memcfg(void) 35{ 36 struct gpio_desc gpio[4]; 37 u8 memcfg = 0; 38 ofnode node; 39 int i, ret; 40 41 node = ofnode_path("/config"); 42 if (!ofnode_valid(node)) { 43 printf("%s: no /config node?\n", __func__); 44 return BIT(2) | BIT(0); 45 } 46 47 ret = gpio_request_list_by_name_nodev(node, 48 "dmo,ram-coding-gpios", 49 gpio, ARRAY_SIZE(gpio), 50 GPIOD_IS_IN); 51 for (i = 0; i < ret; i++) 52 memcfg |= !!dm_gpio_get_value(&(gpio[i])) << i; 53 54 gpio_free_list_nodev(gpio, ret); 55 56 return memcfg; 57} 58 59int board_phys_sdram_size(phys_size_t *size) 60{ 61 u8 memcfg = dmo_get_memcfg(); 62 u8 ecc = 0; 63 64 *size = 4ULL >> ((memcfg >> 1) & 0x3); 65 66 if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) { 67 /* 896 MiB, i.e. 1 GiB without 12.5% reserved for in-band ECC */ 68 ecc = readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK; 69 } 70 71 *size *= SZ_1G - (ecc ? (SZ_1G / 8) : 0); 72 73 return 0; 74} 75 76#ifdef CONFIG_SPL_BUILD 77static void data_modul_imx_edm_sbc_early_init_f(const iomux_v3_cfg_t wdog_pad) 78{ 79 struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; 80 81 imx_iomux_v3_setup_pad(wdog_pad | MUX_PAD_CTRL(WDOG_PAD_CTRL)); 82 83 set_wdog_reset(wdog); 84} 85 86__weak int data_modul_imx_edm_sbc_board_power_init(void) 87{ 88 return 0; 89} 90 91static void spl_dram_init(struct dram_timing_info *dram_timing_info[8]) 92{ 93 u8 memcfg = dmo_get_memcfg(); 94 int i; 95 96 printf("DDR: %d GiB x%d [0x%x]\n", 97 /* 0..4 GiB, 1..2 GiB, 0..1 GiB */ 98 4 >> ((memcfg >> 1) & 0x3), 99 /* 0..x32, 1..x16 */ 100 32 >> (memcfg & BIT(0)), 101 memcfg); 102 103 if (!dram_timing_info[memcfg]) { 104 printf("Unsupported DRAM strapping, trying lowest supported. MEMCFG=0x%x\n", 105 memcfg); 106 for (i = 7; i >= 0; i--) 107 if (dram_timing_info[i]) /* Configuration found */ 108 break; 109 } 110 111 ddr_init(dram_timing_info[memcfg]); 112 113 if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) { 114 printf("DDR: Inline ECC %sabled\n", 115 (readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK) ? 116 "en" : "dis"); 117 } 118} 119 120void dmo_board_init_f(const iomux_v3_cfg_t wdog_pad, 121 struct dram_timing_info *dram_timing_info[8]) 122{ 123 struct udevice *dev; 124 int ret; 125 126 icache_enable(); 127 128 arch_cpu_init(); 129 130 init_uart_clk(2); 131 132 data_modul_imx_edm_sbc_early_init_f(wdog_pad); 133 134 /* Clear the BSS. */ 135 memset(__bss_start, 0, __bss_end - __bss_start); 136 137 ret = spl_early_init(); 138 if (ret) { 139 debug("spl_early_init() failed: %d\n", ret); 140 hang(); 141 } 142 143 preloader_console_init(); 144 145 ret = uclass_get_device_by_name(UCLASS_CLK, 146 "clock-controller@30380000", 147 &dev); 148 if (ret < 0) { 149 printf("Failed to find clock node. Check device tree\n"); 150 hang(); 151 } 152 153 enable_tzc380(); 154 155 data_modul_imx_edm_sbc_board_power_init(); 156 157 /* DDR initialization */ 158 spl_dram_init(dram_timing_info); 159 160 board_init_r(NULL, 0); 161} 162#else 163void dmo_setup_boot_device(void) 164{ 165 int boot_device = get_boot_device(); 166 char *devnum; 167 168 devnum = env_get("devnum"); 169 if (devnum) /* devnum is already set */ 170 return; 171 172 if (boot_device == MMC3_BOOT) /* eMMC */ 173 env_set_ulong("devnum", 0); 174 else 175 env_set_ulong("devnum", 1); 176} 177 178void dmo_setup_mac_address(void) 179{ 180 unsigned char enetaddr[6]; 181 struct udevice *dev; 182 int off, ret; 183 184 ret = eth_env_get_enetaddr("ethaddr", enetaddr); 185 if (ret) /* ethaddr is already set */ 186 return; 187 188 off = fdt_path_offset(gd->fdt_blob, "eeprom0"); 189 if (off < 0) { 190 printf("%s: No eeprom0 path offset\n", __func__); 191 return; 192 } 193 194 ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev); 195 if (ret) { 196 printf("Cannot find EEPROM!\n"); 197 return; 198 } 199 200 ret = i2c_eeprom_read(dev, 0xb0, enetaddr, 0x6); 201 if (ret) { 202 printf("Error reading configuration EEPROM!\n"); 203 return; 204 } 205 206 if (is_valid_ethaddr(enetaddr)) 207 eth_env_set_enetaddr("ethaddr", enetaddr); 208} 209#endif 210