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