1983e3700STom Rini /* 2983e3700STom Rini * Copyright 2011 Linaro Limited 3983e3700STom Rini * Aneesh V <aneesh@ti.com> 4983e3700STom Rini * 5983e3700STom Rini * SPDX-License-Identifier: GPL-2.0+ 6983e3700STom Rini */ 7983e3700STom Rini #include <common.h> 85d982856SSimon Glass #include <asm/setup.h> 9983e3700STom Rini #include <asm/arch/sys_proto.h> 10983e3700STom Rini static void do_cancel_out(u32 *num, u32 *den, u32 factor) 11983e3700STom Rini { 12983e3700STom Rini while (1) { 13983e3700STom Rini if (((*num)/factor*factor == (*num)) && 14983e3700STom Rini ((*den)/factor*factor == (*den))) { 15983e3700STom Rini (*num) /= factor; 16983e3700STom Rini (*den) /= factor; 17983e3700STom Rini } else 18983e3700STom Rini break; 19983e3700STom Rini } 20983e3700STom Rini } 21983e3700STom Rini 22*fa24eca1SSemen Protsenko #ifdef CONFIG_FASTBOOT_FLASH 23*fa24eca1SSemen Protsenko static void omap_set_fastboot_cpu(void) 24*fa24eca1SSemen Protsenko { 25*fa24eca1SSemen Protsenko char *cpu; 26*fa24eca1SSemen Protsenko u32 cpu_rev = omap_revision(); 27*fa24eca1SSemen Protsenko 28*fa24eca1SSemen Protsenko switch (cpu_rev) { 29*fa24eca1SSemen Protsenko case DRA752_ES1_0: 30*fa24eca1SSemen Protsenko case DRA752_ES1_1: 31*fa24eca1SSemen Protsenko case DRA752_ES2_0: 32*fa24eca1SSemen Protsenko cpu = "DRA752"; 33*fa24eca1SSemen Protsenko break; 34*fa24eca1SSemen Protsenko case DRA722_ES1_0: 35*fa24eca1SSemen Protsenko case DRA722_ES2_0: 36*fa24eca1SSemen Protsenko cpu = "DRA722"; 37*fa24eca1SSemen Protsenko break; 38*fa24eca1SSemen Protsenko default: 39*fa24eca1SSemen Protsenko cpu = NULL; 40*fa24eca1SSemen Protsenko printf("Warning: fastboot.cpu: unknown CPU rev: %u\n", cpu_rev); 41*fa24eca1SSemen Protsenko } 42*fa24eca1SSemen Protsenko 43*fa24eca1SSemen Protsenko setenv("fastboot.cpu", cpu); 44*fa24eca1SSemen Protsenko } 45*fa24eca1SSemen Protsenko 46*fa24eca1SSemen Protsenko static void omap_set_fastboot_secure(void) 47*fa24eca1SSemen Protsenko { 48*fa24eca1SSemen Protsenko const char *secure; 49*fa24eca1SSemen Protsenko u32 dev = get_device_type(); 50*fa24eca1SSemen Protsenko 51*fa24eca1SSemen Protsenko switch (dev) { 52*fa24eca1SSemen Protsenko case EMU_DEVICE: 53*fa24eca1SSemen Protsenko secure = "EMU"; 54*fa24eca1SSemen Protsenko break; 55*fa24eca1SSemen Protsenko case HS_DEVICE: 56*fa24eca1SSemen Protsenko secure = "HS"; 57*fa24eca1SSemen Protsenko break; 58*fa24eca1SSemen Protsenko case GP_DEVICE: 59*fa24eca1SSemen Protsenko secure = "GP"; 60*fa24eca1SSemen Protsenko break; 61*fa24eca1SSemen Protsenko default: 62*fa24eca1SSemen Protsenko secure = NULL; 63*fa24eca1SSemen Protsenko printf("Warning: fastboot.secure: unknown CPU sec: %u\n", dev); 64*fa24eca1SSemen Protsenko } 65*fa24eca1SSemen Protsenko 66*fa24eca1SSemen Protsenko setenv("fastboot.secure", secure); 67*fa24eca1SSemen Protsenko } 68*fa24eca1SSemen Protsenko 69*fa24eca1SSemen Protsenko static void omap_set_fastboot_board_rev(void) 70*fa24eca1SSemen Protsenko { 71*fa24eca1SSemen Protsenko const char *board_rev; 72*fa24eca1SSemen Protsenko 73*fa24eca1SSemen Protsenko board_rev = getenv("board_rev"); 74*fa24eca1SSemen Protsenko if (board_rev == NULL) 75*fa24eca1SSemen Protsenko printf("Warning: fastboot.board_rev: unknown board revision\n"); 76*fa24eca1SSemen Protsenko 77*fa24eca1SSemen Protsenko setenv("fastboot.board_rev", board_rev); 78*fa24eca1SSemen Protsenko } 79*fa24eca1SSemen Protsenko 80*fa24eca1SSemen Protsenko #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV 81*fa24eca1SSemen Protsenko static u32 omap_mmc_get_part_size(const char *part) 82*fa24eca1SSemen Protsenko { 83*fa24eca1SSemen Protsenko int res; 84*fa24eca1SSemen Protsenko struct blk_desc *dev_desc; 85*fa24eca1SSemen Protsenko disk_partition_t info; 86*fa24eca1SSemen Protsenko u64 sz = 0; 87*fa24eca1SSemen Protsenko 88*fa24eca1SSemen Protsenko dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); 89*fa24eca1SSemen Protsenko if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { 90*fa24eca1SSemen Protsenko error("invalid mmc device\n"); 91*fa24eca1SSemen Protsenko return 0; 92*fa24eca1SSemen Protsenko } 93*fa24eca1SSemen Protsenko 94*fa24eca1SSemen Protsenko res = part_get_info_by_name(dev_desc, part, &info); 95*fa24eca1SSemen Protsenko if (res < 0) { 96*fa24eca1SSemen Protsenko error("cannot find partition: '%s'\n", part); 97*fa24eca1SSemen Protsenko return 0; 98*fa24eca1SSemen Protsenko } 99*fa24eca1SSemen Protsenko 100*fa24eca1SSemen Protsenko /* Calculate size in bytes */ 101*fa24eca1SSemen Protsenko sz = (info.size * (u64)info.blksz); 102*fa24eca1SSemen Protsenko /* to KiB */ 103*fa24eca1SSemen Protsenko sz >>= 10; 104*fa24eca1SSemen Protsenko 105*fa24eca1SSemen Protsenko return (u32)sz; 106*fa24eca1SSemen Protsenko } 107*fa24eca1SSemen Protsenko 108*fa24eca1SSemen Protsenko static void omap_set_fastboot_userdata_size(void) 109*fa24eca1SSemen Protsenko { 110*fa24eca1SSemen Protsenko char buf[16]; 111*fa24eca1SSemen Protsenko u32 sz_kb; 112*fa24eca1SSemen Protsenko 113*fa24eca1SSemen Protsenko sz_kb = omap_mmc_get_part_size("userdata"); 114*fa24eca1SSemen Protsenko if (sz_kb == 0) { 115*fa24eca1SSemen Protsenko buf[0] = '\0'; 116*fa24eca1SSemen Protsenko printf("Warning: fastboot.userdata_size: unable to calc\n"); 117*fa24eca1SSemen Protsenko } else { 118*fa24eca1SSemen Protsenko sprintf(buf, "%u", sz_kb); 119*fa24eca1SSemen Protsenko } 120*fa24eca1SSemen Protsenko 121*fa24eca1SSemen Protsenko setenv("fastboot.userdata_size", buf); 122*fa24eca1SSemen Protsenko } 123*fa24eca1SSemen Protsenko #else 124*fa24eca1SSemen Protsenko static inline void omap_set_fastboot_userdata_size(void) 125*fa24eca1SSemen Protsenko { 126*fa24eca1SSemen Protsenko } 127*fa24eca1SSemen Protsenko #endif /* CONFIG_FASTBOOT_FLASH_MMC_DEV */ 128*fa24eca1SSemen Protsenko void omap_set_fastboot_vars(void) 129*fa24eca1SSemen Protsenko { 130*fa24eca1SSemen Protsenko omap_set_fastboot_cpu(); 131*fa24eca1SSemen Protsenko omap_set_fastboot_secure(); 132*fa24eca1SSemen Protsenko omap_set_fastboot_board_rev(); 133*fa24eca1SSemen Protsenko omap_set_fastboot_userdata_size(); 134*fa24eca1SSemen Protsenko } 135*fa24eca1SSemen Protsenko #endif /* CONFIG_FASTBOOT_FLASH */ 136*fa24eca1SSemen Protsenko 137983e3700STom Rini /* 138983e3700STom Rini * Cancel out the denominator and numerator of a fraction 139983e3700STom Rini * to get smaller numerator and denominator. 140983e3700STom Rini */ 141983e3700STom Rini void cancel_out(u32 *num, u32 *den, u32 den_limit) 142983e3700STom Rini { 143983e3700STom Rini do_cancel_out(num, den, 2); 144983e3700STom Rini do_cancel_out(num, den, 3); 145983e3700STom Rini do_cancel_out(num, den, 5); 146983e3700STom Rini do_cancel_out(num, den, 7); 147983e3700STom Rini do_cancel_out(num, den, 11); 148983e3700STom Rini do_cancel_out(num, den, 13); 149983e3700STom Rini do_cancel_out(num, den, 17); 150983e3700STom Rini while ((*den) > den_limit) { 151983e3700STom Rini *num /= 2; 152983e3700STom Rini /* 153983e3700STom Rini * Round up the denominator so that the final fraction 154983e3700STom Rini * (num/den) is always <= the desired value 155983e3700STom Rini */ 156983e3700STom Rini *den = (*den + 1) / 2; 157983e3700STom Rini } 158983e3700STom Rini } 159983e3700STom Rini 160983e3700STom Rini __weak void omap_die_id(unsigned int *die_id) 161983e3700STom Rini { 162983e3700STom Rini die_id[0] = die_id[1] = die_id[2] = die_id[3] = 0; 163983e3700STom Rini } 164983e3700STom Rini 165983e3700STom Rini void omap_die_id_serial(void) 166983e3700STom Rini { 167983e3700STom Rini unsigned int die_id[4] = { 0 }; 168983e3700STom Rini char serial_string[17] = { 0 }; 169983e3700STom Rini 170983e3700STom Rini omap_die_id((unsigned int *)&die_id); 171983e3700STom Rini 172983e3700STom Rini if (!getenv("serial#")) { 173983e3700STom Rini snprintf(serial_string, sizeof(serial_string), 174983e3700STom Rini "%08x%08x", die_id[0], die_id[3]); 175983e3700STom Rini 176983e3700STom Rini setenv("serial#", serial_string); 177983e3700STom Rini } 178983e3700STom Rini } 179983e3700STom Rini 180983e3700STom Rini void omap_die_id_get_board_serial(struct tag_serialnr *serialnr) 181983e3700STom Rini { 182983e3700STom Rini char *serial_string; 183983e3700STom Rini unsigned long long serial; 184983e3700STom Rini 185983e3700STom Rini serial_string = getenv("serial#"); 186983e3700STom Rini 187983e3700STom Rini if (serial_string) { 188983e3700STom Rini serial = simple_strtoull(serial_string, NULL, 16); 189983e3700STom Rini 190983e3700STom Rini serialnr->high = (unsigned int) (serial >> 32); 191983e3700STom Rini serialnr->low = (unsigned int) (serial & 0xffffffff); 192983e3700STom Rini } else { 193983e3700STom Rini serialnr->high = 0; 194983e3700STom Rini serialnr->low = 0; 195983e3700STom Rini } 196983e3700STom Rini } 197983e3700STom Rini 198983e3700STom Rini void omap_die_id_usbethaddr(void) 199983e3700STom Rini { 200983e3700STom Rini unsigned int die_id[4] = { 0 }; 201983e3700STom Rini unsigned char mac[6] = { 0 }; 202983e3700STom Rini 203983e3700STom Rini omap_die_id((unsigned int *)&die_id); 204983e3700STom Rini 205983e3700STom Rini if (!getenv("usbethaddr")) { 206983e3700STom Rini /* 207983e3700STom Rini * Create a fake MAC address from the processor ID code. 208983e3700STom Rini * First byte is 0x02 to signify locally administered. 209983e3700STom Rini */ 210983e3700STom Rini mac[0] = 0x02; 211983e3700STom Rini mac[1] = die_id[3] & 0xff; 212983e3700STom Rini mac[2] = die_id[2] & 0xff; 213983e3700STom Rini mac[3] = die_id[1] & 0xff; 214983e3700STom Rini mac[4] = die_id[0] & 0xff; 215983e3700STom Rini mac[5] = (die_id[0] >> 8) & 0xff; 216983e3700STom Rini 217983e3700STom Rini eth_setenv_enetaddr("usbethaddr", mac); 218983e3700STom Rini } 219983e3700STom Rini } 220983e3700STom Rini 221983e3700STom Rini void omap_die_id_display(void) 222983e3700STom Rini { 223983e3700STom Rini unsigned int die_id[4] = { 0 }; 224983e3700STom Rini 225983e3700STom Rini omap_die_id(die_id); 226983e3700STom Rini 227983e3700STom Rini printf("OMAP die ID: %08x%08x%08x%08x\n", die_id[3], die_id[2], 228983e3700STom Rini die_id[1], die_id[0]); 229983e3700STom Rini } 230