1 /* 2 * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 #include <common.h> 7 #include <dm.h> 8 #include <misc.h> 9 #include <ram.h> 10 #include <dm/pinctrl.h> 11 #include <dm/uclass-internal.h> 12 #include <misc.h> 13 #include <asm/setup.h> 14 #include <asm/arch/periph.h> 15 #include <power/regulator.h> 16 #include <u-boot/sha256.h> 17 18 #define RK3399_CPUID_OFF 0x7 19 #define RK3399_CPUID_LEN 0x10 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define RK3399_CPUID_OFF 0x7 24 #define RK3399_CPUID_LEN 0x10 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 int board_init(void) 29 { 30 struct udevice *pinctrl, *regulator; 31 int ret; 32 33 /* 34 * The PWM does not have decicated interrupt number in dts and can 35 * not get periph_id by pinctrl framework, so let's init them here. 36 * The PWM2 and PWM3 are for pwm regulators. 37 */ 38 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 39 if (ret) { 40 debug("%s: Cannot find pinctrl device\n", __func__); 41 goto out; 42 } 43 44 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2); 45 if (ret) { 46 debug("%s PWM2 pinctrl init fail!\n", __func__); 47 goto out; 48 } 49 50 /* rk3399 need to init vdd_center to get the correct output voltage */ 51 ret = regulator_get_by_platname("vdd_center", ®ulator); 52 if (ret) 53 debug("%s: Cannot get vdd_center regulator\n", __func__); 54 55 ret = regulator_get_by_platname("vcc5v0_host", ®ulator); 56 if (ret) { 57 debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret); 58 goto out; 59 } 60 61 ret = regulator_set_enable(regulator, true); 62 if (ret) { 63 debug("%s vcc5v0-host-en set fail!\n", __func__); 64 goto out; 65 } 66 67 out: 68 return 0; 69 } 70 71 static void setup_serial(void) 72 { 73 #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) 74 struct udevice *dev; 75 int ret, i; 76 u8 cpuid[RK3399_CPUID_LEN]; 77 u8 low[RK3399_CPUID_LEN/2], high[RK3399_CPUID_LEN/2]; 78 char cpuid_str[RK3399_CPUID_LEN * 2 + 1]; 79 u64 serialno; 80 char serialno_str[16]; 81 82 /* the first misc device will be used */ 83 ret = uclass_get_device(UCLASS_MISC, 0, &dev); 84 if (ret) { 85 debug("%s: could not find efuse device\n", __func__); 86 return; 87 } 88 89 /* read the cpu_id range from the efuses */ 90 ret = misc_read(dev, RK3399_CPUID_OFF, &cpuid, sizeof(cpuid)); 91 if (ret) { 92 debug("%s: reading cpuid from the efuses failed\n", 93 __func__); 94 return; 95 } 96 97 memset(cpuid_str, 0, sizeof(cpuid_str)); 98 for (i = 0; i < 16; i++) 99 sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]); 100 101 debug("cpuid: %s\n", cpuid_str); 102 103 /* 104 * Mix the cpuid bytes using the same rules as in 105 * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c 106 */ 107 for (i = 0; i < 8; i++) { 108 low[i] = cpuid[1 + (i << 1)]; 109 high[i] = cpuid[i << 1]; 110 } 111 112 serialno = crc32_no_comp(0, low, 8); 113 serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; 114 snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno); 115 116 setenv("cpuid#", cpuid_str); 117 setenv("serial#", serialno_str); 118 #endif 119 120 return; 121 } 122 123 int misc_init_r(void) 124 { 125 setup_serial(); 126 127 return 0; 128 } 129 130 #ifdef CONFIG_SERIAL_TAG 131 void get_board_serial(struct tag_serialnr *serialnr) 132 { 133 char *serial_string; 134 u64 serial = 0; 135 136 serial_string = getenv("serial#"); 137 138 if (serial_string) 139 serial = simple_strtoull(serial_string, NULL, 16); 140 141 serialnr->high = (u32)(serial >> 32); 142 serialnr->low = (u32)(serial & 0xffffffff); 143 } 144 #endif 145 146 int dram_init(void) 147 { 148 struct ram_info ram; 149 struct udevice *dev; 150 int ret; 151 152 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 153 if (ret) { 154 debug("DRAM init failed: %d\n", ret); 155 return ret; 156 } 157 ret = ram_get_info(dev, &ram); 158 if (ret) { 159 debug("Cannot get DRAM size: %d\n", ret); 160 return ret; 161 } 162 debug("SDRAM base=%llx, size=%x\n", ram.base, (unsigned int)ram.size); 163 gd->ram_size = ram.size; 164 165 return 0; 166 } 167 168 int dram_init_banksize(void) 169 { 170 /* Reserve 0x200000 for ATF bl31 */ 171 gd->bd->bi_dram[0].start = 0x200000; 172 gd->bd->bi_dram[0].size = 0x7e000000; 173 174 return 0; 175 } 176