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/ddr.h>
9#include <asm/arch/sys_proto.h>
10#include <asm/io.h>
11#include <dm.h>
12#include <env.h>
13#include <env_internal.h>
14#include <i2c_eeprom.h>
15#include <malloc.h>
16#include <net.h>
17#include <miiphy.h>
18
19#include "lpddr4_timing.h"
20#include "../common/dh_common.h"
21#include "../common/dh_imx.h"
22
23DECLARE_GLOBAL_DATA_PTR;
24
25int mach_cpu_init(void)
26{
27	icache_enable();
28	return 0;
29}
30
31int board_phys_sdram_size(phys_size_t *size)
32{
33	const u16 memsz[] = { 512, 1024, 1536, 2048, 3072, 4096, 6144, 8192 };
34	const u8 ecc = readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK;
35	u8 memcfg = dh_get_memcfg();
36
37	/* 896 kiB, i.e. 1 MiB without 12.5% reserved for in-band ECC */
38	*size = (u64)memsz[memcfg] * (SZ_1M - (ecc ? (SZ_1M / 8) : 0));
39
40	return 0;
41}
42
43static int dh_imx8_setup_ethaddr(void)
44{
45	unsigned char enetaddr[6];
46
47	if (dh_mac_is_in_env("ethaddr"))
48		return 0;
49
50	if (dh_get_mac_is_enabled("ethernet0"))
51		return 0;
52
53	if (!dh_imx_get_mac_from_fuse(enetaddr))
54		goto out;
55
56	if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0"))
57		goto out;
58
59	return -ENXIO;
60
61out:
62	return eth_env_set_enetaddr("ethaddr", enetaddr);
63}
64
65static int dh_imx8_setup_eth1addr(void)
66{
67	unsigned char enetaddr[6];
68
69	if (dh_mac_is_in_env("eth1addr"))
70		return 0;
71
72	if (dh_get_mac_is_enabled("ethernet1"))
73		return 0;
74
75	if (!dh_imx_get_mac_from_fuse(enetaddr))
76		goto increment_out;
77
78	if (!dh_get_mac_from_eeprom(enetaddr, "eeprom1"))
79		goto out;
80
81	/*
82	 * Populate second ethernet MAC from first ethernet EEPROM with MAC
83	 * address LSByte incremented by 1. This is only used on SoMs without
84	 * second ethernet EEPROM, i.e. early prototypes.
85	 */
86	if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0"))
87		goto increment_out;
88
89	return -ENXIO;
90
91increment_out:
92	enetaddr[5]++;
93
94out:
95	return eth_env_set_enetaddr("eth1addr", enetaddr);
96}
97
98int dh_setup_mac_address(void)
99{
100	int ret;
101
102	ret = dh_imx8_setup_ethaddr();
103	if (ret)
104		printf("%s: Unable to setup ethaddr! ret = %d\n", __func__, ret);
105
106	ret = dh_imx8_setup_eth1addr();
107	if (ret)
108		printf("%s: Unable to setup eth1addr! ret = %d\n", __func__, ret);
109
110	return ret;
111}
112
113int board_init(void)
114{
115	return 0;
116}
117
118int board_late_init(void)
119{
120	dh_setup_mac_address();
121	return 0;
122}
123
124enum env_location env_get_location(enum env_operation op, int prio)
125{
126	return prio ? ENVL_UNKNOWN : ENVL_SPI_FLASH;
127}
128