xref: /rk3399_rockchip-uboot/board/phytec/phycore_rk3288/phycore-rk3288.c (revision 822b9c09c16a6b2244ecd7f73e113c00db7584a8)
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