ARM: imx: Switch Data Modul i.MX8M Mini eDM SBC to USB251x Hub driver
[platform/kernel/u-boot.git] / board / data_modul / imx8mm_edm_sbc / imx8mm_data_modul_edm_sbc.c
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/arch/clock.h>
8 #include <asm/arch/sys_proto.h>
9 #include <asm/io.h>
10 #include <asm/mach-imx/boot_mode.h>
11 #include <dm.h>
12 #include <dm/device-internal.h>
13 #include <i2c_eeprom.h>
14 #include <malloc.h>
15 #include <net.h>
16 #include <spl.h>
17
18 #include "lpddr4_timing.h"
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 int mach_cpu_init(void)
23 {
24         icache_enable();
25         return 0;
26 }
27
28 int board_phys_sdram_size(phys_size_t *size)
29 {
30         u8 memcfg = dmo_get_memcfg();
31
32         *size = (4ULL >> ((memcfg >> 1) & 0x3)) * SZ_1G;
33
34         return 0;
35 }
36
37 /* IMX8M SNVS registers needed for the bootcount functionality */
38 #define SNVS_BASE_ADDR                  0x30370000
39 #define SNVS_LPSR                       0x4c
40 #define SNVS_LPLVDR                     0x64
41 #define SNVS_LPPGDR_INIT                0x41736166
42
43 static void setup_snvs(void)
44 {
45         /* Enable SNVS clock */
46         clock_enable(CCGR_SNVS, 1);
47         /* Initialize glitch detect */
48         writel(SNVS_LPPGDR_INIT, SNVS_BASE_ADDR + SNVS_LPLVDR);
49         /* Clear interrupt status */
50         writel(0xffffffff, SNVS_BASE_ADDR + SNVS_LPSR);
51 }
52
53 static void setup_mac_address(void)
54 {
55         unsigned char enetaddr[6];
56         struct udevice *dev;
57         int off, ret;
58
59         ret = eth_env_get_enetaddr("ethaddr", enetaddr);
60         if (ret)        /* ethaddr is already set */
61                 return;
62
63         off = fdt_path_offset(gd->fdt_blob, "eeprom0");
64         if (off < 0) {
65                 printf("%s: No eeprom0 path offset\n", __func__);
66                 return;
67         }
68
69         ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
70         if (ret) {
71                 printf("Cannot find EEPROM!\n");
72                 return;
73         }
74
75         ret = i2c_eeprom_read(dev, 0xb0, enetaddr, 0x6);
76         if (ret) {
77                 printf("Error reading configuration EEPROM!\n");
78                 return;
79         }
80
81         if (is_valid_ethaddr(enetaddr))
82                 eth_env_set_enetaddr("ethaddr", enetaddr);
83 }
84
85 static void setup_boot_device(void)
86 {
87         int boot_device = get_boot_device();
88         char *devnum;
89
90         devnum = env_get("devnum");
91         if (devnum)     /* devnum is already set */
92                 return;
93
94         if (boot_device == MMC3_BOOT)   /* eMMC */
95                 env_set_ulong("devnum", 0);
96         else
97                 env_set_ulong("devnum", 1);
98 }
99
100 int board_init(void)
101 {
102         setup_snvs();
103         return 0;
104 }
105
106 int board_late_init(void)
107 {
108         struct udevice *dev;
109         int ret;
110
111         setup_boot_device();
112         setup_mac_address();
113
114         ret = uclass_get_device_by_name(UCLASS_MISC, "usb-hub@2c", &dev);
115         if (ret)
116                 printf("Error bringing up USB hub (%d)\n", ret);
117
118         return 0;
119 }