1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2011 Linaro Limited 4 * Aneesh V <aneesh@ti.com> 5 */ 6 #include <common.h> 7 #include <environment.h> 8 #include <asm/setup.h> 9 #include <asm/arch/sys_proto.h> 10 #include <asm/omap_common.h> 11 12 static void do_cancel_out(u32 *num, u32 *den, u32 factor) 13 { 14 while (1) { 15 if (((*num)/factor*factor == (*num)) && 16 ((*den)/factor*factor == (*den))) { 17 (*num) /= factor; 18 (*den) /= factor; 19 } else 20 break; 21 } 22 } 23 24 #ifdef CONFIG_FASTBOOT_FLASH 25 static void omap_set_fastboot_cpu(void) 26 { 27 char *cpu; 28 u32 cpu_rev = omap_revision(); 29 30 switch (cpu_rev) { 31 case DRA762_ES1_0: 32 case DRA762_ABZ_ES1_0: 33 case DRA762_ACD_ES1_0: 34 cpu = "DRA762"; 35 break; 36 case DRA752_ES1_0: 37 case DRA752_ES1_1: 38 case DRA752_ES2_0: 39 cpu = "DRA752"; 40 break; 41 case DRA722_ES1_0: 42 case DRA722_ES2_0: 43 case DRA722_ES2_1: 44 cpu = "DRA722"; 45 break; 46 default: 47 cpu = NULL; 48 printf("Warning: fastboot.cpu: unknown CPU rev: %u\n", cpu_rev); 49 } 50 51 env_set("fastboot.cpu", cpu); 52 } 53 54 static void omap_set_fastboot_secure(void) 55 { 56 const char *secure; 57 u32 dev = get_device_type(); 58 59 switch (dev) { 60 case EMU_DEVICE: 61 secure = "EMU"; 62 break; 63 case HS_DEVICE: 64 secure = "HS"; 65 break; 66 case GP_DEVICE: 67 secure = "GP"; 68 break; 69 default: 70 secure = NULL; 71 printf("Warning: fastboot.secure: unknown CPU sec: %u\n", dev); 72 } 73 74 env_set("fastboot.secure", secure); 75 } 76 77 static void omap_set_fastboot_board_rev(void) 78 { 79 const char *board_rev; 80 81 board_rev = env_get("board_rev"); 82 if (board_rev == NULL) 83 printf("Warning: fastboot.board_rev: unknown board revision\n"); 84 85 env_set("fastboot.board_rev", board_rev); 86 } 87 88 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV 89 static u32 omap_mmc_get_part_size(const char *part) 90 { 91 int res; 92 struct blk_desc *dev_desc; 93 disk_partition_t info; 94 u64 sz = 0; 95 96 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); 97 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { 98 pr_err("invalid mmc device\n"); 99 return 0; 100 } 101 102 /* Check only for EFI (GPT) partition table */ 103 res = part_get_info_by_name_type(dev_desc, part, &info, PART_TYPE_EFI); 104 if (res < 0) 105 return 0; 106 107 /* Calculate size in bytes */ 108 sz = (info.size * (u64)info.blksz); 109 /* to KiB */ 110 sz >>= 10; 111 112 return (u32)sz; 113 } 114 115 static void omap_set_fastboot_userdata_size(void) 116 { 117 char buf[16]; 118 u32 sz_kb; 119 120 sz_kb = omap_mmc_get_part_size("userdata"); 121 if (sz_kb == 0) 122 return; /* probably it's not Android partition table */ 123 124 sprintf(buf, "%u", sz_kb); 125 env_set("fastboot.userdata_size", buf); 126 } 127 #else 128 static inline void omap_set_fastboot_userdata_size(void) 129 { 130 } 131 #endif /* CONFIG_FASTBOOT_FLASH_MMC_DEV */ 132 void omap_set_fastboot_vars(void) 133 { 134 omap_set_fastboot_cpu(); 135 omap_set_fastboot_secure(); 136 omap_set_fastboot_board_rev(); 137 omap_set_fastboot_userdata_size(); 138 } 139 #endif /* CONFIG_FASTBOOT_FLASH */ 140 141 /* 142 * Cancel out the denominator and numerator of a fraction 143 * to get smaller numerator and denominator. 144 */ 145 void cancel_out(u32 *num, u32 *den, u32 den_limit) 146 { 147 do_cancel_out(num, den, 2); 148 do_cancel_out(num, den, 3); 149 do_cancel_out(num, den, 5); 150 do_cancel_out(num, den, 7); 151 do_cancel_out(num, den, 11); 152 do_cancel_out(num, den, 13); 153 do_cancel_out(num, den, 17); 154 while ((*den) > den_limit) { 155 *num /= 2; 156 /* 157 * Round up the denominator so that the final fraction 158 * (num/den) is always <= the desired value 159 */ 160 *den = (*den + 1) / 2; 161 } 162 } 163 164 __weak void omap_die_id(unsigned int *die_id) 165 { 166 die_id[0] = die_id[1] = die_id[2] = die_id[3] = 0; 167 } 168 169 void omap_die_id_serial(void) 170 { 171 unsigned int die_id[4] = { 0 }; 172 char serial_string[17] = { 0 }; 173 174 omap_die_id((unsigned int *)&die_id); 175 176 if (!env_get("serial#")) { 177 snprintf(serial_string, sizeof(serial_string), 178 "%08x%08x", die_id[0], die_id[3]); 179 180 env_set("serial#", serial_string); 181 } 182 } 183 184 void omap_die_id_get_board_serial(struct tag_serialnr *serialnr) 185 { 186 char *serial_string; 187 unsigned long long serial; 188 189 serial_string = env_get("serial#"); 190 191 if (serial_string) { 192 serial = simple_strtoull(serial_string, NULL, 16); 193 194 serialnr->high = (unsigned int) (serial >> 32); 195 serialnr->low = (unsigned int) (serial & 0xffffffff); 196 } else { 197 serialnr->high = 0; 198 serialnr->low = 0; 199 } 200 } 201 202 void omap_die_id_usbethaddr(void) 203 { 204 unsigned int die_id[4] = { 0 }; 205 unsigned char mac[6] = { 0 }; 206 207 omap_die_id((unsigned int *)&die_id); 208 209 if (!env_get("usbethaddr")) { 210 /* 211 * Create a fake MAC address from the processor ID code. 212 * First byte is 0x02 to signify locally administered. 213 */ 214 mac[0] = 0x02; 215 mac[1] = die_id[3] & 0xff; 216 mac[2] = die_id[2] & 0xff; 217 mac[3] = die_id[1] & 0xff; 218 mac[4] = die_id[0] & 0xff; 219 mac[5] = (die_id[0] >> 8) & 0xff; 220 221 eth_env_set_enetaddr("usbethaddr", mac); 222 223 if (!env_get("ethaddr")) 224 eth_env_set_enetaddr("ethaddr", mac); 225 } 226 } 227 228 void omap_die_id_display(void) 229 { 230 unsigned int die_id[4] = { 0 }; 231 232 omap_die_id(die_id); 233 234 printf("OMAP die ID: %08x%08x%08x%08x\n", die_id[3], die_id[2], 235 die_id[1], die_id[0]); 236 } 237