diff options
Diffstat (limited to 'board/data_modul/common/common.c')
-rw-r--r-- | board/data_modul/common/common.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/board/data_modul/common/common.c b/board/data_modul/common/common.c new file mode 100644 index 00000000000..bf9a11472d1 --- /dev/null +++ b/board/data_modul/common/common.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Marek Vasut <marex@denx.de> + */ + +#include <common.h> +#include <asm-generic/gpio.h> +#include <asm-generic/sections.h> +#include <asm/arch/clock.h> +#include <asm/arch/ddr.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <common.h> +#include <dm/uclass.h> +#include <hang.h> +#include <i2c_eeprom.h> +#include <image.h> +#include <init.h> +#include <net.h> +#include <spl.h> + +#include <dm/uclass.h> +#include <dm/device.h> +#include <dm/uclass-internal.h> +#include <dm/device-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) + +u8 dmo_get_memcfg(void) +{ + struct gpio_desc gpio[4]; + u8 memcfg = 0; + ofnode node; + int i, ret; + + node = ofnode_path("/config"); + if (!ofnode_valid(node)) { + printf("%s: no /config node?\n", __func__); + return BIT(2) | BIT(0); + } + + ret = gpio_request_list_by_name_nodev(node, + "dmo,ram-coding-gpios", + gpio, ARRAY_SIZE(gpio), + GPIOD_IS_IN); + for (i = 0; i < ret; i++) + memcfg |= !!dm_gpio_get_value(&(gpio[i])) << i; + + gpio_free_list_nodev(gpio, ret); + + return memcfg; +} + +int board_phys_sdram_size(phys_size_t *size) +{ + u8 memcfg = dmo_get_memcfg(); + + *size = (4ULL >> ((memcfg >> 1) & 0x3)) * SZ_1G; + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +static void data_modul_imx_edm_sbc_early_init_f(const iomux_v3_cfg_t wdog_pad) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + imx_iomux_v3_setup_pad(wdog_pad | MUX_PAD_CTRL(WDOG_PAD_CTRL)); + + set_wdog_reset(wdog); +} + +__weak int data_modul_imx_edm_sbc_board_power_init(void) +{ + return 0; +} + +static void spl_dram_init(struct dram_timing_info *dram_timing_info[8]) +{ + u8 memcfg = dmo_get_memcfg(); + int i; + + printf("DDR: %d GiB x%d [0x%x]\n", + /* 0..4 GiB, 1..2 GiB, 0..1 GiB */ + 4 >> ((memcfg >> 1) & 0x3), + /* 0..x32, 1..x16 */ + 32 >> (memcfg & BIT(0)), + memcfg); + + if (!dram_timing_info[memcfg]) { + printf("Unsupported DRAM strapping, trying lowest supported. MEMCFG=0x%x\n", + memcfg); + for (i = 7; i >= 0; i--) + if (dram_timing_info[i]) /* Configuration found */ + break; + } + + ddr_init(dram_timing_info[memcfg]); +} + +void dmo_board_init_f(const iomux_v3_cfg_t wdog_pad, + struct dram_timing_info *dram_timing_info[8]) +{ + struct udevice *dev; + int ret; + + icache_enable(); + + arch_cpu_init(); + + init_uart_clk(2); + + data_modul_imx_edm_sbc_early_init_f(wdog_pad); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + + preloader_console_init(); + + ret = uclass_get_device_by_name(UCLASS_CLK, + "clock-controller@30380000", + &dev); + if (ret < 0) { + printf("Failed to find clock node. Check device tree\n"); + hang(); + } + + enable_tzc380(); + + data_modul_imx_edm_sbc_board_power_init(); + + /* DDR initialization */ + spl_dram_init(dram_timing_info); + + board_init_r(NULL, 0); +} +#else +void dmo_setup_boot_device(void) +{ + int boot_device = get_boot_device(); + char *devnum; + + devnum = env_get("devnum"); + if (devnum) /* devnum is already set */ + return; + + if (boot_device == MMC3_BOOT) /* eMMC */ + env_set_ulong("devnum", 0); + else + env_set_ulong("devnum", 1); +} + +void dmo_setup_mac_address(void) +{ + unsigned char enetaddr[6]; + struct udevice *dev; + int off, ret; + + ret = eth_env_get_enetaddr("ethaddr", enetaddr); + if (ret) /* ethaddr is already set */ + return; + + off = fdt_path_offset(gd->fdt_blob, "eeprom0"); + if (off < 0) { + printf("%s: No eeprom0 path offset\n", __func__); + return; + } + + ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev); + if (ret) { + printf("Cannot find EEPROM!\n"); + return; + } + + ret = i2c_eeprom_read(dev, 0xb0, enetaddr, 0x6); + if (ret) { + printf("Error reading configuration EEPROM!\n"); + return; + } + + if (is_valid_ethaddr(enetaddr)) + eth_env_set_enetaddr("ethaddr", enetaddr); +} +#endif |