1bafcf2dbSWadim Egorov /*
2bafcf2dbSWadim Egorov * Copyright (C) 2017 PHYTEC Messtechnik GmbH
3bafcf2dbSWadim Egorov * Author: Wadim Egorov <w.egorov@phytec.de>
4bafcf2dbSWadim Egorov *
5bafcf2dbSWadim Egorov * SPDX-License-Identifier: GPL-2.0+
6bafcf2dbSWadim Egorov */
7bafcf2dbSWadim Egorov
832191a39SWadim Egorov #include <asm/io.h>
9bafcf2dbSWadim Egorov #include <common.h>
1032191a39SWadim Egorov #include <dm.h>
1132191a39SWadim Egorov #include <i2c.h>
1232191a39SWadim Egorov #include <i2c_eeprom.h>
1332191a39SWadim Egorov #include <netdev.h>
1432191a39SWadim Egorov #include "som.h"
15*822b9c09SKever Yang #include <power/rk8xx_pmic.h>
1632191a39SWadim Egorov
valid_rk3288_som(struct rk3288_som * som)1732191a39SWadim Egorov static int valid_rk3288_som(struct rk3288_som *som)
1832191a39SWadim Egorov {
1932191a39SWadim Egorov unsigned char *p = (unsigned char *)som;
2032191a39SWadim Egorov unsigned char *e = p + sizeof(struct rk3288_som) - 1;
2132191a39SWadim Egorov int hw = 0;
2232191a39SWadim Egorov
2332191a39SWadim Egorov while (p < e) {
2432191a39SWadim Egorov hw += hweight8(*p);
2532191a39SWadim Egorov p++;
2632191a39SWadim Egorov }
2732191a39SWadim Egorov
2832191a39SWadim Egorov return hw == som->bs;
2932191a39SWadim Egorov }
3032191a39SWadim Egorov
31fc983935SKever Yang #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_OF_PLATDATA)
phycore_init(void)32fc983935SKever Yang static int phycore_init(void)
33fc983935SKever Yang {
34fc983935SKever Yang struct udevice *pmic;
35fc983935SKever Yang int ret;
36fc983935SKever Yang
37fc983935SKever Yang ret = uclass_first_device_err(UCLASS_PMIC, &pmic);
38fc983935SKever Yang if (ret)
39fc983935SKever Yang return ret;
40fc983935SKever Yang
41fc983935SKever Yang #if defined(CONFIG_SPL_POWER_SUPPORT)
42fc983935SKever Yang /* Increase USB input current to 2A */
43fc983935SKever Yang ret = rk818_spl_configure_usb_input_current(pmic, 2000);
44fc983935SKever Yang if (ret)
45fc983935SKever Yang return ret;
46fc983935SKever Yang
47fc983935SKever Yang /* Close charger when USB lower then 3.26V */
48fc983935SKever Yang ret = rk818_spl_configure_usb_chrg_shutdown(pmic, 3260000);
49fc983935SKever Yang if (ret)
50fc983935SKever Yang return ret;
51fc983935SKever Yang #endif
52fc983935SKever Yang
53fc983935SKever Yang return 0;
54fc983935SKever Yang }
55fc983935SKever Yang
rk_board_init_f(void)56fc983935SKever Yang int rk_board_init_f(void)
57fc983935SKever Yang {
58fc983935SKever Yang int ret = 0;
59fc983935SKever Yang
60fc983935SKever Yang if (of_machine_is_compatible("phytec,rk3288-phycore-som")) {
61fc983935SKever Yang ret = phycore_init();
62fc983935SKever Yang if (ret) {
63fc983935SKever Yang debug("Failed to set up phycore power settings: %d\n",
64fc983935SKever Yang ret);
65fc983935SKever Yang return ret;
66fc983935SKever Yang }
67fc983935SKever Yang }
68fc983935SKever Yang
69fc983935SKever Yang return 0;
70fc983935SKever Yang }
71fc983935SKever Yang #endif
72fc983935SKever Yang
rk3288_board_late_init(void)73fc983935SKever Yang int rk3288_board_late_init(void)
7432191a39SWadim Egorov {
7532191a39SWadim Egorov int ret;
7632191a39SWadim Egorov struct udevice *dev;
7732191a39SWadim Egorov struct rk3288_som opt;
7832191a39SWadim Egorov int off;
7932191a39SWadim Egorov
8032191a39SWadim Egorov /* Get the identificatioin page of M24C32-D EEPROM */
8132191a39SWadim Egorov off = fdt_path_offset(gd->fdt_blob, "eeprom0");
8232191a39SWadim Egorov if (off < 0) {
8332191a39SWadim Egorov printf("%s: No eeprom0 path offset\n", __func__);
8432191a39SWadim Egorov return off;
8532191a39SWadim Egorov }
8632191a39SWadim Egorov
8732191a39SWadim Egorov ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
8832191a39SWadim Egorov if (ret) {
8932191a39SWadim Egorov printf("%s: Could not find EEPROM\n", __func__);
9032191a39SWadim Egorov return ret;
9132191a39SWadim Egorov }
9232191a39SWadim Egorov
9332191a39SWadim Egorov ret = i2c_set_chip_offset_len(dev, 2);
9432191a39SWadim Egorov if (ret)
9532191a39SWadim Egorov return ret;
9632191a39SWadim Egorov
9732191a39SWadim Egorov ret = i2c_eeprom_read(dev, 0, (uint8_t *)&opt,
9832191a39SWadim Egorov sizeof(struct rk3288_som));
9932191a39SWadim Egorov if (ret) {
10032191a39SWadim Egorov printf("%s: Could not read EEPROM\n", __func__);
10132191a39SWadim Egorov return ret;
10232191a39SWadim Egorov }
10332191a39SWadim Egorov
10432191a39SWadim Egorov if (opt.api_version != 0 || !valid_rk3288_som(&opt)) {
10532191a39SWadim Egorov printf("Invalid data or wrong EEPROM layout version.\n");
10632191a39SWadim Egorov /* Proceed anyway, since there is no fallback option */
10732191a39SWadim Egorov }
10832191a39SWadim Egorov
10932191a39SWadim Egorov if (is_valid_ethaddr(opt.mac))
11032191a39SWadim Egorov eth_env_set_enetaddr("ethaddr", opt.mac);
11132191a39SWadim Egorov
11232191a39SWadim Egorov return 0;
11332191a39SWadim Egorov }
114