/* ------------------------------------------------------------------------*//** * @FUNCTION cpu_full_name_set * @BRIEF set CPU full name (name + rev + type) * @RETURNS 0 in case of success * OMAPCONF_ERR_INTERNAL * @param[in] none * @DESCRIPTION set CPU full name (name + rev + type) *//*------------------------------------------------------------------------ */ static int cpu_full_name_set(void) { char name[CPU_NAME_MAX_LENGTH]; char rev[CPU_REVISION_MAX_NAME_LENGTH]; char type[CPU_DEVICE_TYPE_MAX_NAME_LENGTH]; strncpy(cpu_full_name, "", sizeof(cpu_full_name)); cpu_gets(name); if (name == NULL) { fprintf(stderr, "%s(): name == NULL!\n", __func__); return OMAPCONF_ERR_INTERNAL; } cpu_revision_gets(rev); if (rev == NULL) { fprintf(stderr, "%s(): rev == NULL!\n", __func__); return OMAPCONF_ERR_INTERNAL; } cpu_device_type_gets(type); if (type == NULL) { fprintf(stderr, "%s(): type == NULL!\n", __func__); return OMAPCONF_ERR_INTERNAL; } if (cpu_is_forced() == 1) strcat(cpu_full_name, "FORCED "); strcat(cpu_full_name, name); strcat(cpu_full_name, " ES"); strcat(cpu_full_name, rev); strcat(cpu_full_name, " ("); strcat(cpu_full_name, type); strcat(cpu_full_name, ")"); dprintf("%s(): cpu_full_name=%s\n", __func__, cpu_full_name); return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION smps_id2vdd_id * @BRIEF convert SMPS ID into VDD ID (for a given platform) * @RETURNS valid VDD ID in case of success * OMAP4_VD_ID_MAX in case of error (OMAP4) * VDD54XX_ID_MAX in case of error (OMAP5) * @param[in] smps_id: valid SMPS ID * @DESCRIPTION convert SMPS ID into VDD ID (for a given platform) *//*------------------------------------------------------------------------ */ unsigned short smps_id2vdd_id(pmic_smps_id smps_id) { unsigned short vdd_id; char name[16]; switch (cpu_get()) { case OMAP_4430: case OMAP_4460: case OMAP_4470: if (smps_id > PMIC_SMPS_ID_MAX) { fprintf(stderr, "%s(): incorrect smps_id! (%u)\n", __func__, smps_id); vdd_id = (unsigned short) OMAP4_VD_ID_MAX; strncpy(name, "FIXME", 16); } else { vdd_id = smps_id + 1; voltdm44xx_get_name(vdd_id, name); } break; case OMAP_5430: case OMAP_5432: if (smps_id > PMIC_SMPS_ID_MAX) { fprintf(stderr, "%s(): incorrect smps_id! (%u)\n", __func__, smps_id); vdd_id = (unsigned short) VDD54XX_ID_MAX; strncpy(name, "FIXME", 16); } else { vdd_id = smps_id + 1; strncpy(name, voltdm54xx_name_get(vdd_id), 16); } break; case DRA_75X: if (smps_id > PMIC_SMPS_ID_MAX) { fprintf(stderr, "%s(): incorrect smps_id! (%u)\n", __func__, smps_id); vdd_id = (unsigned short) VDD_DRA7XX_ID_MAX; strncpy(name, "FIXME", 16); } else { switch (smps_id) { case PMIC_SMPS_MPU: vdd_id = VDD_DRA7XX_MPU; break; case PMIC_SMPS_CORE: vdd_id = VDD_DRA7XX_CORE; break; case PMIC_SMPS_MM: vdd_id = VDD_DRA7XX_IVA; break; case PMIC_SMPS_DSPEVE: vdd_id = VDD_DRA7XX_DSPEVE; break; case PMIC_SMPS_GPU: vdd_id = VDD_DRA7XX_GPU; break; default: vdd_id = VDD_DRA7XX_ID_MAX; } strncpy(name, voltdm54xx_name_get(vdd_id), 16); } break; case AM_3352: case AM_3354: case AM_3356: case AM_3357: case AM_3358: case AM_3359: if (smps_id > PMIC_SMPS_ID_MAX) { fprintf(stderr, "%s(): incorrect smps_id! (%u)\n", __func__, smps_id); vdd_id = (unsigned short) VDD_AM335X_ID_MAX; strncpy(name, "FIXME", 16); } else { switch (smps_id) { case PMIC_SMPS_MPU: vdd_id = VDD_AM335X_MPU; break; case PMIC_SMPS_CORE: vdd_id = VDD_AM335X_CORE; break; default: vdd_id = VDD_AM335X_ID_MAX; } strncpy(name, voltdm_am335x_name_get(vdd_id), 16); } break; default: fprintf(stderr, "%s(): unsupported CPU! (%s)\n", __func__, cpu_gets(name)); vdd_id = (unsigned short) VDD54XX_ID_MAX; strncpy(name, "FIXME", 16); } dprintf("%s(): smps_id=%s => vdd_id=%s\n", __func__, smps_name_get(smps_id), name); return vdd_id; }
/* ------------------------------------------------------------------------*//** * @FUNCTION vdd_id2smps_id * @BRIEF convert VDD ID into SMPS ID (for a given platform) * @RETURNS valid SMPS ID in case of success * PMIC_SMPS_ID_MAX in case of error * @param[in] vdd_id: valid VDD ID * @DESCRIPTION convert VDD ID into SMPS ID (for a given platform) *//*------------------------------------------------------------------------ */ pmic_smps_id vdd_id2smps_id(unsigned short vdd_id) { pmic_smps_id smps_id; char smps_name[16]; char vdd_name[16]; switch (cpu_get()) { case OMAP_4430: case OMAP_4460: case OMAP_4470: voltdm44xx_get_name(vdd_id, vdd_name); if ((vdd_id == OMAP4_LDO_WKUP) || (vdd_id > OMAP4_VDD_CORE)) { fprintf(stderr, "%s(): incorrect vdd_id! (%u)\n", __func__, vdd_id); smps_id = PMIC_SMPS_ID_MAX; strncpy(smps_name, "FIXME", 16); } else { smps_id = vdd_id - 1; strncpy(smps_name, smps_name_get(smps_id), 16); } break; case OMAP_5430: case OMAP_5432: strncpy(vdd_name, voltdm54xx_name_get(vdd_id), 16); if ((vdd_id == VDD54XX_WKUP) || (vdd_id > VDD54XX_CORE)) { fprintf(stderr, "%s(): incorrect vdd_id! (%u)\n", __func__, vdd_id); smps_id = PMIC_SMPS_ID_MAX; strncpy(smps_name, "FIXME", 16); } else { smps_id = vdd_id - 1; strncpy(smps_name, smps_name_get(smps_id), 16); } break; case DRA_75X: strncpy(vdd_name, voltdm_dra7xx_name_get(vdd_id), 16); if (vdd_id > VDD_DRA7XX_RTC) { fprintf(stderr, "%s(): incorrect vdd_id! (%u)\n", __func__, vdd_id); smps_id = PMIC_SMPS_ID_MAX; strncpy(smps_name, "FIXME", 16); } else { switch (vdd_id) { case VDD_DRA7XX_MPU: smps_id = PMIC_SMPS_MPU; break; case VDD_DRA7XX_CORE: smps_id = PMIC_SMPS_CORE; break; case VDD_DRA7XX_IVA: smps_id = PMIC_SMPS_MM; break; case VDD_DRA7XX_DSPEVE: smps_id = PMIC_SMPS_DSPEVE; break; case VDD_DRA7XX_GPU: smps_id = PMIC_SMPS_GPU; break; default: smps_id = PMIC_SMPS_ID_MAX; } strncpy(smps_name, smps_name_get(smps_id), 16); } break; case AM_3352: case AM_3354: case AM_3356: case AM_3357: case AM_3358: case AM_3359: strncpy(vdd_name, voltdm_am335x_name_get(vdd_id), 16); if (vdd_id > VDD_AM335X_RTC) { fprintf(stderr, "%s(): incorrect vdd_id! (%u)\n", __func__, vdd_id); smps_id = PMIC_SMPS_ID_MAX; strncpy(smps_name, "FIXME", 16); } else { switch (vdd_id) { case VDD_AM335X_MPU: smps_id = PMIC_SMPS_MPU; break; case VDD_AM335X_CORE: smps_id = PMIC_SMPS_CORE; break; default: smps_id = PMIC_SMPS_ID_MAX; } strncpy(smps_name, smps_name_get(smps_id), 16); } break; default: fprintf(stderr, "%s(): unsupported CPU! (%s)\n", __func__, cpu_gets(smps_name)); smps_id = PMIC_SMPS_ID_MAX; strncpy(smps_name, "FIXME", 16); } dprintf("%s(): vdd_id=%s => smps_id=%s\n", __func__, vdd_name, smps_name); return smps_id; }
/* ------------------------------------------------------------------------*//** * @FUNCTION cpu_detect * @BRIEF Detect cpu and set internal global variables accordingly * @RETURNS 0 on success * OMAPCONF_ERR_UNEXPECTED * OMAPCONF_ERR_CPU if cpu not recognized * OMAPCONF_ERR_REG_ACCESS * @param[in] none * @DESCRIPTION Detect cpu and set internal global variables accordingly *//*------------------------------------------------------------------------ */ int cpu_detect(void) { unsigned int status; unsigned int efuse; unsigned int prod_id_1; int ret; unsigned char status_bit_start; #ifdef CPUID_DEBUG char s[CPU_FULL_NAME_MAX_LENGTH]; char rev_s[CPU_REVISION_MAX_NAME_LENGTH]; char dev_type_s[CPU_DEVICE_TYPE_MAX_NAME_LENGTH]; #endif /* Init variables */ cpu_init(); /* Retrieve OMAP chip & ES */ /* Determine if device is of the AM or OMAP family */ if (cpu_is_omap()) ret = identify_omap(); else ret = identify_sitara(); if (ret) return ret; dprintf("%s(): Chip is %s ES%s\n", __func__, cpu_gets(s), cpu_revision_gets(rev_s)); /* Retrieve device type */ if (cpu_is_omap44xx()) { ret = mem_read(OMAP44XX_STATUS, &status); status_bit_start = 8; } else if (cpu_is_omap54xx() || cpu_is_dra7xx()) { ret = mem_read(OMAP54XX_STATUS, &status); status_bit_start = 6; } else if (cpu_is_am335x() || cpu_is_am437x()) { ret = mem_read(AM335X_STATUS, &status); status_bit_start = 8; } else { ret = -1; } if (ret) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): OMAP44XX_STATUS = 0x%08X\n", __func__, status); switch (extract_bitfield(status, status_bit_start, 2)) { case 3: cpu_device_type_set(DEV_GP); break; case 2: cpu_device_type_set(DEV_HS); break; case 1: cpu_device_type_set(DEV_EMU); break; default: cpu_device_type_set(DEV_TEST); } dprintf("%s(): Device Type is %s\n", __func__, cpu_device_type_gets(dev_type_s)); /* Retrieve silicon performance type from EFuse */ if (cpu_is_omap44xx()) { if (mem_read(CONTROL_STD_FUSE_PROD_ID_1, &prod_id_1) != 0) { fprintf(stderr, "omapconf (%s()): could not read CONTROL_STD_FUSE_PROD_ID_1 register!\n", __func__); return OMAPCONF_ERR_REG_ACCESS; } dprintf("%s(): CONTROL_STD_FUSE_PROD_ID_1 = 0x%08X\n", __func__, prod_id_1); si_type = (silicon_type) extract_bitfield(prod_id_1, 16, 2); } else if (cpu_is_omap54xx()) { if (cpu_revision_get() == REV_ES1_0) { if (cpu_silicon_max_speed_get() != 1200) cpu_silicon_type_set(STANDARD_PERF_SI); else cpu_silicon_type_set(SPEEDBIN_SI); } else { if (cpu_silicon_max_speed_get() != 1700) cpu_silicon_type_set(STANDARD_PERF_SI); else cpu_silicon_type_set(SPEEDBIN_SI); } } else if (cpu_is_dra7xx()) { /* TBD: implement true detection when ID data is available */ cpu_silicon_type_set(STANDARD_PERF_SI); } else if (cpu_is_am335x()){ if (mem_read(EFUSE_SMA_REG, &efuse) != 0) { fprintf(stderr, "omapconf: (%s()): could not read EFUSE_SMA register!\n", __func__); return OMAPCONF_ERR_REG_ACCESS; } switch (extract_bitfield(efuse, 16, 2)) { case 0: /* * Silicon revision 1.0 does not support EFUSE SMA REG * (returns all 0's if read) * Setting as unknown until there is an alternate method */ cpu_package_type_set(PACKAGE_TYPE_MAX); break; case 1: cpu_package_type_set(ZCZ); break; case 2: cpu_package_type_set(ZCE); break; default: fprintf(stderr, "omapconf: (%s()): could not identify package type!\n", __func__); return OMAPCONF_ERR_UNEXPECTED; } } dprintf("%s(): Silicon performance type is %s (%uMHz)\n", __func__, cpu_silicon_type_gets(s), cpu_silicon_max_speed_get()); /* Set CPU full name */ cpu_full_name_set(); dprintf("%s(): CPU full name is %s\n", __func__, cpu_full_name); return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION cpu_detect * @BRIEF Detect cpu and set internal global variables accordingly * @RETURNS 0 on success * OMAPCONF_ERR_UNEXPECTED * OMAPCONF_ERR_CPU if cpu not recognized * OMAPCONF_ERR_REG_ACCESS * @param[in] none * @DESCRIPTION Detect cpu and set internal global variables accordingly *//*------------------------------------------------------------------------ */ int cpu_detect(void) { unsigned int id_code; unsigned int status; unsigned int prod_id_1; #ifdef CPUID_DEBUG char s[CPU_FULL_NAME_MAX_LENGTH]; char rev_s[CPU_REVISION_MAX_NAME_LENGTH]; char dev_type_s[CPU_DEVICE_TYPE_MAX_NAME_LENGTH]; #endif /* Init variables */ cpu_init(); /* Retrieve OMAP chip & ES */ if (mem_read(ID_CODE, &id_code) != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): ID_CODE = 0x%08X\n", __func__, id_code); switch (id_code) { case OMAP5432_ES_1_0_ID_CODE: cpu_set(OMAP_5432); cpu_revision_set(REV_ES1_0); break; case OMAP5430_ES_1_0_ID_CODE: case 0x0000002F: /* Zebu */ cpu_set(OMAP_5430); cpu_revision_set(REV_ES1_0); break; case OMAP4470_ES_1_0_ID_CODE: cpu_set(OMAP_4470); cpu_revision_set(REV_ES1_0); break; case OMAP4460_ES_1_1_ID_CODE: cpu_set(OMAP_4460); cpu_revision_set(REV_ES1_1); break; case OMAP4460_ES_1_0_ID_CODE: cpu_set(OMAP_4460); cpu_revision_set(REV_ES1_0); break; case OMAP4430_ES_2_3_ID_CODE: cpu_set(OMAP_4430); cpu_revision_set(REV_ES2_3); break; case OMAP4430_ES_2_2_ID_CODE: cpu_set(OMAP_4430); cpu_revision_set(REV_ES2_2); break; case OMAP4430_ES_2_1_ID_CODE: cpu_set(OMAP_4430); cpu_revision_set(REV_ES2_1); break; case OMAP4430_ES_2_0_ID_CODE: case OMAP4430_ES_1_0_ID_CODE: /* * Due to fusing issue between ES1.0 and ES2.0 (same code...), * revision cannot be correctly detected. * Workaround is to use Cortex-A9 own revision code, which did * changed, but it is not accessible from user space... * Only way is to use /proc/cpuinfo. */ cpu_set(OMAP_4430); cpu_rev_get_from_cpuinfo(&cpu_rev); switch (cpu_rev) { case REV_ES2_0: cpu_revision_set(REV_ES2_0); break; case REV_ES1_0: cpu_revision_set(REV_ES1_0); break; default: dprintf("%s(): unknown ARM Cortex-A9!\n", __func__); return OMAPCONF_ERR_UNEXPECTED; } break; default: dprintf("%s(): OMAP ID CODE not recognized! (0x%08X)\n", __func__, id_code); return OMAPCONF_ERR_CPU; } dprintf("%s(): Chip is %s ES%s\n", __func__, cpu_gets(s), cpu_revision_gets(rev_s)); /* Retrieve device type */ if (mem_read(OMAP44XX_STATUS, &status) != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): OMAP44XX_STATUS = 0x%08X\n", __func__, status); switch (extract_bitfield(status, 8, 2)) { case 3: cpu_device_type_set(DEV_GP); break; case 2: cpu_device_type_set(DEV_HS); break; case 1: cpu_device_type_set(DEV_EMU); break; default: cpu_device_type_set(DEV_TEST); } dprintf("%s(): Device Type is %s\n", __func__, cpu_device_type_gets(dev_type_s)); /* Retrieve silicon performance type from EFuse */ if (mem_read(CONTROL_STD_FUSE_PROD_ID_1, &prod_id_1) != 0) { fprintf(stderr, "omapconf (%s()): could not read CONTROL_STD_FUSE_PROD_ID_1 register!\n", __func__); return OMAPCONF_ERR_REG_ACCESS; } dprintf("%s(): CONTROL_STD_FUSE_PROD_ID_1 = 0x%08X\n", __func__, prod_id_1); si_type = (silicon_type) extract_bitfield(prod_id_1, 16, 2); dprintf("%s(): Silicon performance type is %s (%uMHz)\n", __func__, cpu_silicon_type_gets(s), cpu_silicon_max_speed_get()); /* Set CPU full name */ cpu_full_name_set(); dprintf("%s(): CPU full name is %s\n", __func__, cpu_full_name); return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION lib54xx_export * @BRIEF export OMAP registers in XML format into file * @RETURNS 0 in case of success * OMAPCONF_ERR_ARG otherwise * @param[in] file: export file name (default if == NULL) * @DESCRIPTION export OMAP registers in XML format into file. If no * file name provided, generate one using current date. *//*------------------------------------------------------------------------ */ int lib54xx_export(char *file) { FILE *fp = NULL; char default_file[64]; char export_date[32]; char version[RELEASE_VERSION_MAX_LENGTH]; char type[RELEASE_TYPE_MAX_LENGTH]; char date[RELEASE_DATE_MAX_LENGTH]; char kversion[KERNEL_VERSION_MAX_LENGTH]; char kauthor[KERNEL_AUTHOR_MAX_LENGTH]; char ktoolchain[KERNEL_TOOLCHAIN_MAX_LENGTH]; char ktype[KERNEL_TYPE_MAX_LENGTH]; char kdate[KERNEL_DATE_MAX_LENGTH]; char dev_name[CPU_NAME_MAX_LENGTH]; char dev_rev[CPU_REVISION_MAX_NAME_LENGTH]; char dev_type[CPU_DEVICE_TYPE_MAX_NAME_LENGTH]; char dev_si_type[CPU_SI_TYPE_MAX_NAME_LENGTH]; unsigned int dev_max_speed; unsigned int i; time_t t; struct tm *tmp; CHECK_CPU(54xx, OMAPCONF_ERR_CPU); /* Get date */ t = time(NULL); tmp = localtime(&t); /* Open export file */ if (file == NULL) { /* No file name given, generate default one */ strcpy(default_file, "omapconf_export_Mon_Jan_01_00_00_00_CET_1970.xml"); if (tmp != NULL) strftime(default_file, 64, "omapconf_export_%a_%b_%d_%H_%M_%S_%Z_%Y.xml", tmp); fp = fopen(default_file, "w"); } else { fp = fopen(file, "w"); } if (fp == NULL) { printf("Oups... could not create %s!!!\n\n", file); return 0; } /* XML header */ fprintf(fp, "<?xml version=\"1.0\"?>\n\n"); strcpy(export_date, "Mon Jan 01 00:00:00 CET 1970"); if (tmp != NULL) strftime(export_date, sizeof(export_date), "%a %b %d %H:%M:%S %Z %Y", tmp); fprintf(fp, "<omapconf_export export_date=\"%s\" omapconf_version=\"%u.%u\" omapconf_builddate=\"%s\">\n", export_date, OMAPCONF_REV_MAJOR, OMAPCONF_REV_MINOR, builddate); release_details_get(version, type, date); if (os_is_android()) fprintf(fp, " <buildinfo os=\"android\" version=\"%s\" type=\"%s\" date=\"%s\">\n", version, type, date); else fprintf(fp, " <buildinfo os=\"linux\" version=\"%s\">\n", version); kernel_details_get(kversion, kauthor, ktoolchain, ktype, kdate); fprintf(fp, " <kernel version=\"%s\" author=\"%s\" toolchain=\"%s\" type=\"%s\" date=\"%s\">\n", kversion, kauthor, ktoolchain, ktype, kdate); cpu_gets(dev_name); cpu_revision_gets(dev_rev); cpu_device_type_gets(dev_type); cpu_silicon_type_gets(dev_si_type); dev_max_speed = cpu_silicon_max_speed_get(); fprintf(fp, " <device name=\"%s\" revision=\"%s\" type=\"%s\" silicon_type=\"%s\" max_speed_mhz=\"%u\">\n", dev_name, dev_rev, dev_type, dev_si_type, dev_max_speed); /* Export PRM registers */ fprintf(fp, " <module name=\"PRM\">\n"); for (i = 0; i < PRM54XX_MODS_COUNT; i++) { if ((cpu_revision_get() != REV_ES1_0) && (i == PRM54XX_L4PER_PRM)) /* L4_PER does not exist on ES2.x */ continue; prm54xx_export(fp, (prm54xx_mod_id) i); } fprintf(fp, " </module>\n"); /* Export CM registers */ fprintf(fp, " <module name=\"CM\">\n"); for (i = 0; i < CM54XX_MODS_COUNT; i++) { if ((cpu_revision_get() != REV_ES1_0) && (i == CM54XX_L4PER_CM_CORE)) /* Does not exist on ES2.x */ continue; cm54xx_export(fp, (cm54xx_mod_id) i); } fprintf(fp, " </module>\n"); /* Export Smart-Reflex registers */ fprintf(fp, " <module name=\"SR\">\n"); sr54xx_export(fp, SR54XX_SMARTREFLEX_MPU); sr54xx_export(fp, SR54XX_SMARTREFLEX_MM); sr54xx_export(fp, SR54XX_SMARTREFLEX_CORE); fprintf(fp, " </module>\n"); /* Export CONTROL MODULE registers */ fprintf(fp, " <module name=\"CONTROL MODULE\">\n"); ctrlmod54xx_export(fp, CTRLMOD54XX_CTRL_MODULE_CORE); ctrlmod54xx_export(fp, CTRLMOD54XX_CTRL_MODULE_CORE_PAD); ctrlmod54xx_export(fp, CTRLMOD54XX_CTRL_MODULE_WKUP); ctrlmod54xx_export(fp, CTRLMOD54XX_CTRL_MODULE_WKUP_PAD); fprintf(fp, " </module>\n"); /* Export EMIF registers */ fprintf(fp, " <module name=\"EMIF\">\n"); emif54xx_export(fp, EMIF54XX_EMIF1); emif54xx_export(fp, EMIF54XX_EMIF2); fprintf(fp, " </module>\n"); fprintf(fp, " </device>\n"); fprintf(fp, " </kernel>\n"); fprintf(fp, " </build>\n"); fprintf(fp, "</omapconf_export>"); /* Close file */ if (fp != NULL) fclose(fp); if (file == NULL) printf("Registers successfully exported in \"%s\" file.\n\n", default_file); else printf("Registers successfully exported in \"%s\" file.\n\n", file); return 0; }