1a13110a9SKlaus Goger /* 2a13110a9SKlaus Goger * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH 3a13110a9SKlaus Goger * 4a13110a9SKlaus Goger * SPDX-License-Identifier: GPL-2.0+ 5a13110a9SKlaus Goger */ 6a13110a9SKlaus Goger #include <common.h> 7a13110a9SKlaus Goger #include <dm.h> 8e92e5803SPhilipp Tomsich #include <misc.h> 9e92e5803SPhilipp Tomsich #include <ram.h> 10a13110a9SKlaus Goger #include <dm/pinctrl.h> 11a13110a9SKlaus Goger #include <dm/uclass-internal.h> 129415b9a7SPhilipp Tomsich #include <asm/setup.h> 13a13110a9SKlaus Goger #include <asm/arch/periph.h> 14a13110a9SKlaus Goger #include <power/regulator.h> 15e92e5803SPhilipp Tomsich #include <u-boot/sha256.h> 16e92e5803SPhilipp Tomsich 17a13110a9SKlaus Goger DECLARE_GLOBAL_DATA_PTR; 18a13110a9SKlaus Goger 19a13110a9SKlaus Goger int board_init(void) 20a13110a9SKlaus Goger { 21a13110a9SKlaus Goger struct udevice *pinctrl, *regulator; 22a13110a9SKlaus Goger int ret; 23a13110a9SKlaus Goger 24a13110a9SKlaus Goger /* 25a13110a9SKlaus Goger * The PWM does not have decicated interrupt number in dts and can 26a13110a9SKlaus Goger * not get periph_id by pinctrl framework, so let's init them here. 27a13110a9SKlaus Goger * The PWM2 and PWM3 are for pwm regulators. 28a13110a9SKlaus Goger */ 29a13110a9SKlaus Goger ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 30a13110a9SKlaus Goger if (ret) { 31a13110a9SKlaus Goger debug("%s: Cannot find pinctrl device\n", __func__); 32a13110a9SKlaus Goger goto out; 33a13110a9SKlaus Goger } 34a13110a9SKlaus Goger 35a13110a9SKlaus Goger ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2); 36a13110a9SKlaus Goger if (ret) { 37a13110a9SKlaus Goger debug("%s PWM2 pinctrl init fail!\n", __func__); 38a13110a9SKlaus Goger goto out; 39a13110a9SKlaus Goger } 40a13110a9SKlaus Goger 41a13110a9SKlaus Goger /* rk3399 need to init vdd_center to get the correct output voltage */ 42a13110a9SKlaus Goger ret = regulator_get_by_platname("vdd_center", ®ulator); 43a13110a9SKlaus Goger if (ret) 44a13110a9SKlaus Goger debug("%s: Cannot get vdd_center regulator\n", __func__); 45a13110a9SKlaus Goger 46a13110a9SKlaus Goger ret = regulator_get_by_platname("vcc5v0_host", ®ulator); 47a13110a9SKlaus Goger if (ret) { 48a13110a9SKlaus Goger debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret); 49a13110a9SKlaus Goger goto out; 50a13110a9SKlaus Goger } 51a13110a9SKlaus Goger 52a13110a9SKlaus Goger ret = regulator_set_enable(regulator, true); 53a13110a9SKlaus Goger if (ret) { 54a13110a9SKlaus Goger debug("%s vcc5v0-host-en set fail!\n", __func__); 55a13110a9SKlaus Goger goto out; 56a13110a9SKlaus Goger } 57a13110a9SKlaus Goger 58a13110a9SKlaus Goger out: 59a13110a9SKlaus Goger return 0; 60a13110a9SKlaus Goger } 61a13110a9SKlaus Goger 628adc9d18SKlaus Goger static void setup_macaddr(void) 638adc9d18SKlaus Goger { 648adc9d18SKlaus Goger #if CONFIG_IS_ENABLED(CMD_NET) 658adc9d18SKlaus Goger int ret; 668adc9d18SKlaus Goger const char *cpuid = getenv("cpuid#"); 678adc9d18SKlaus Goger u8 hash[SHA256_SUM_LEN]; 688adc9d18SKlaus Goger int size = sizeof(hash); 698adc9d18SKlaus Goger u8 mac_addr[6]; 708adc9d18SKlaus Goger 718adc9d18SKlaus Goger /* Only generate a MAC address, if none is set in the environment */ 728adc9d18SKlaus Goger if (getenv("ethaddr")) 738adc9d18SKlaus Goger return; 748adc9d18SKlaus Goger 758adc9d18SKlaus Goger if (!cpuid) { 768adc9d18SKlaus Goger debug("%s: could not retrieve 'cpuid#'\n", __func__); 778adc9d18SKlaus Goger return; 788adc9d18SKlaus Goger } 798adc9d18SKlaus Goger 808adc9d18SKlaus Goger ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size); 818adc9d18SKlaus Goger if (ret) { 828adc9d18SKlaus Goger debug("%s: failed to calculate SHA256\n", __func__); 838adc9d18SKlaus Goger return; 848adc9d18SKlaus Goger } 858adc9d18SKlaus Goger 868adc9d18SKlaus Goger /* Copy 6 bytes of the hash to base the MAC address on */ 878adc9d18SKlaus Goger memcpy(mac_addr, hash, 6); 888adc9d18SKlaus Goger 898adc9d18SKlaus Goger /* Make this a valid MAC address and set it */ 908adc9d18SKlaus Goger mac_addr[0] &= 0xfe; /* clear multicast bit */ 918adc9d18SKlaus Goger mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ 928adc9d18SKlaus Goger eth_setenv_enetaddr("ethaddr", mac_addr); 938adc9d18SKlaus Goger #endif 948adc9d18SKlaus Goger 958adc9d18SKlaus Goger return; 968adc9d18SKlaus Goger } 978adc9d18SKlaus Goger 989415b9a7SPhilipp Tomsich static void setup_serial(void) 999415b9a7SPhilipp Tomsich { 1009415b9a7SPhilipp Tomsich #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) 101*26722335SKever Yang const u32 cpuid_offset = 0x7; 102*26722335SKever Yang const u32 cpuid_length = 0x10; 103*26722335SKever Yang 1049415b9a7SPhilipp Tomsich struct udevice *dev; 1059415b9a7SPhilipp Tomsich int ret, i; 106*26722335SKever Yang u8 cpuid[cpuid_length]; 107*26722335SKever Yang u8 low[cpuid_length/2], high[cpuid_length/2]; 108*26722335SKever Yang char cpuid_str[cpuid_length * 2 + 1]; 1099415b9a7SPhilipp Tomsich u64 serialno; 1109415b9a7SPhilipp Tomsich char serialno_str[16]; 1119415b9a7SPhilipp Tomsich 1128adc9d18SKlaus Goger /* retrieve the device */ 1138adc9d18SKlaus Goger ret = uclass_get_device_by_driver(UCLASS_MISC, 1148adc9d18SKlaus Goger DM_GET_DRIVER(rockchip_efuse), &dev); 1159415b9a7SPhilipp Tomsich if (ret) { 1169415b9a7SPhilipp Tomsich debug("%s: could not find efuse device\n", __func__); 1179415b9a7SPhilipp Tomsich return; 1189415b9a7SPhilipp Tomsich } 1199415b9a7SPhilipp Tomsich 1209415b9a7SPhilipp Tomsich /* read the cpu_id range from the efuses */ 121*26722335SKever Yang ret = misc_read(dev, cpuid_offset, &cpuid, sizeof(cpuid)); 1229415b9a7SPhilipp Tomsich if (ret) { 1239415b9a7SPhilipp Tomsich debug("%s: reading cpuid from the efuses failed\n", 1249415b9a7SPhilipp Tomsich __func__); 1259415b9a7SPhilipp Tomsich return; 1269415b9a7SPhilipp Tomsich } 1279415b9a7SPhilipp Tomsich 1289415b9a7SPhilipp Tomsich memset(cpuid_str, 0, sizeof(cpuid_str)); 1299415b9a7SPhilipp Tomsich for (i = 0; i < 16; i++) 1309415b9a7SPhilipp Tomsich sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]); 1319415b9a7SPhilipp Tomsich 1329415b9a7SPhilipp Tomsich debug("cpuid: %s\n", cpuid_str); 1339415b9a7SPhilipp Tomsich 1349415b9a7SPhilipp Tomsich /* 1359415b9a7SPhilipp Tomsich * Mix the cpuid bytes using the same rules as in 1369415b9a7SPhilipp Tomsich * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c 1379415b9a7SPhilipp Tomsich */ 1389415b9a7SPhilipp Tomsich for (i = 0; i < 8; i++) { 1399415b9a7SPhilipp Tomsich low[i] = cpuid[1 + (i << 1)]; 1409415b9a7SPhilipp Tomsich high[i] = cpuid[i << 1]; 1419415b9a7SPhilipp Tomsich } 1429415b9a7SPhilipp Tomsich 1439415b9a7SPhilipp Tomsich serialno = crc32_no_comp(0, low, 8); 1449415b9a7SPhilipp Tomsich serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; 1459415b9a7SPhilipp Tomsich snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno); 1469415b9a7SPhilipp Tomsich 1479415b9a7SPhilipp Tomsich setenv("cpuid#", cpuid_str); 1489415b9a7SPhilipp Tomsich setenv("serial#", serialno_str); 1499415b9a7SPhilipp Tomsich #endif 1509415b9a7SPhilipp Tomsich 1519415b9a7SPhilipp Tomsich return; 1529415b9a7SPhilipp Tomsich } 1539415b9a7SPhilipp Tomsich 1549415b9a7SPhilipp Tomsich int misc_init_r(void) 1559415b9a7SPhilipp Tomsich { 1569415b9a7SPhilipp Tomsich setup_serial(); 1578adc9d18SKlaus Goger setup_macaddr(); 1589415b9a7SPhilipp Tomsich 1599415b9a7SPhilipp Tomsich return 0; 1609415b9a7SPhilipp Tomsich } 1619415b9a7SPhilipp Tomsich 1629415b9a7SPhilipp Tomsich #ifdef CONFIG_SERIAL_TAG 1639415b9a7SPhilipp Tomsich void get_board_serial(struct tag_serialnr *serialnr) 1649415b9a7SPhilipp Tomsich { 1659415b9a7SPhilipp Tomsich char *serial_string; 1669415b9a7SPhilipp Tomsich u64 serial = 0; 1679415b9a7SPhilipp Tomsich 1689415b9a7SPhilipp Tomsich serial_string = getenv("serial#"); 1699415b9a7SPhilipp Tomsich 1709415b9a7SPhilipp Tomsich if (serial_string) 1719415b9a7SPhilipp Tomsich serial = simple_strtoull(serial_string, NULL, 16); 1729415b9a7SPhilipp Tomsich 1739415b9a7SPhilipp Tomsich serialnr->high = (u32)(serial >> 32); 1749415b9a7SPhilipp Tomsich serialnr->low = (u32)(serial & 0xffffffff); 1759415b9a7SPhilipp Tomsich } 1769415b9a7SPhilipp Tomsich #endif 177