unsigned long long tegra_chip_uid(void) { unsigned long long lo, hi; lo = tegra_fuse_readl(FUSE_UID_LOW); hi = tegra_fuse_readl(FUSE_UID_HIGH); return (hi << 32ull) | lo; }
static unsigned int utmi_phy_xcvr_setup_value(struct tegra_usb_phy *phy) { struct tegra_utmi_config *cfg = &phy->pdata->u_cfg.utmi; signed long val; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); if (cfg->xcvr_use_fuses) { val = FUSE_USB_CALIB_XCVR_SETUP( tegra_fuse_readl(FUSE_USB_CALIB_0)); if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET) val = val + cfg->xcvr_setup_offset; if (val > UTMIP_XCVR_SETUP_MAX_VALUE) { val = UTMIP_XCVR_SETUP_MAX_VALUE; pr_info("%s: reset XCVR_SETUP to max value\n", __func__); } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) { val = UTMIP_XCVR_SETUP_MIN_VALUE; pr_info("%s: reset XCVR_SETUP to min value\n", __func__); } } else { val = cfg->xcvr_setup; } return (unsigned int) val; }
int tegra_sku_id(void) { int sku_id; u32 reg = tegra_fuse_readl(FUSE_SKU_INFO); sku_id = reg & 0xFF; return sku_id; }
int __init loki_sdhci_init(void) { int nominal_core_mv; int min_vcore_override_mv; int boot_vcore_mv; u32 speedo; struct board_info bi; tegra_get_board_info(&bi); if (bi.board_id == BOARD_E2548 && bi.sku == 0x0 && bi.fab == 0x0) { tegra_sdhci_platform_data3.uhs_mask |= MMC_MASK_HS200; tegra_sdhci_platform_data3.max_clk_limit = 102000000; } nominal_core_mv = tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail); if (nominal_core_mv) { tegra_sdhci_platform_data0.nominal_vcore_mv = nominal_core_mv; tegra_sdhci_platform_data2.nominal_vcore_mv = nominal_core_mv; tegra_sdhci_platform_data3.nominal_vcore_mv = nominal_core_mv; } min_vcore_override_mv = tegra_dvfs_rail_get_override_floor(tegra_core_rail); if (min_vcore_override_mv) { tegra_sdhci_platform_data0.min_vcore_override_mv = min_vcore_override_mv; tegra_sdhci_platform_data2.min_vcore_override_mv = min_vcore_override_mv; tegra_sdhci_platform_data3.min_vcore_override_mv = min_vcore_override_mv; } boot_vcore_mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail); if (boot_vcore_mv) { tegra_sdhci_platform_data0.boot_vcore_mv = boot_vcore_mv; tegra_sdhci_platform_data2.boot_vcore_mv = boot_vcore_mv; tegra_sdhci_platform_data3.boot_vcore_mv = boot_vcore_mv; } tegra_sdhci_platform_data0.max_clk_limit = 204000000; speedo = tegra_fuse_readl(FUSE_SOC_SPEEDO_0); tegra_sdhci_platform_data0.cpu_speedo = speedo; tegra_sdhci_platform_data2.cpu_speedo = speedo; tegra_sdhci_platform_data3.cpu_speedo = speedo; platform_device_register(&tegra_sdhci_device3); if (!is_uart_over_sd_enabled()) platform_device_register(&tegra_sdhci_device2); platform_device_register(&tegra_sdhci_device0); loki_wifi_init(); return 0; }
static ssize_t cardhu_backup_chipid_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { char *s = buf; unsigned long reg; unsigned long fab; unsigned long lot; unsigned long i; unsigned long backup_uid; char backup_id[9]; /* fab code */ fab = tegra_fuse_readl(FUSE_FAB_CODE) & FUSE_FAB_CODE_MASK; /* Lot code must be re-encoded from a 5 digit base-36 'BCD' number * to a binary number. */ lot = 0; reg = tegra_fuse_readl(FUSE_LOT_CODE_1) << 2; for (i = 0; i < 5; ++i) { u32 digit = (reg & 0xFC000000) >> 26; BUG_ON(digit >= 36); lot *= 36; lot += digit; reg <<= 6; } backup_uid = 0; /* compose 32-bit backup id by concatenating two bit fields. * <FAB:6><LOT:26> */ backup_uid = ((unsigned long) fab << 26ul) | ((unsigned long) lot); snprintf(backup_id, sizeof(backup_id), "%08lx", backup_uid); strcpy(buf, cardhu_chipid); /* replace 64-bit unique id starting bit#24 with 32-bit backup id */ for (i = 0; i < strlen(backup_id); i++) buf[i + 2] = backup_id[i]; s += sprintf(s, "%s\n", buf); return (s - buf); }
int __init macallan_sdhci_init(void) { #ifndef CONFIG_USE_OF if ((tegra_sdhci_platform_data3.uhs_mask & MMC_MASK_HS200) && (!(tegra_sdhci_platform_data3.uhs_mask & MMC_UHS_MASK_DDR50))) tegra_sdhci_platform_data3.trim_delay = 0; int nominal_core_mv; int min_vcore_override_mv; int boot_vcore_mv; int speedo; nominal_core_mv = tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail); if (nominal_core_mv > 0) { macallan_tegra_sdhci_platform_data0.nominal_vcore_mv = nominal_core_mv; tegra_sdhci_platform_data2.nominal_vcore_mv = nominal_core_mv; tegra_sdhci_platform_data3.nominal_vcore_mv = nominal_core_mv; } min_vcore_override_mv = tegra_dvfs_rail_get_override_floor(tegra_core_rail); if (min_vcore_override_mv) { macallan_tegra_sdhci_platform_data0.min_vcore_override_mv = min_vcore_override_mv; tegra_sdhci_platform_data2.min_vcore_override_mv = min_vcore_override_mv; tegra_sdhci_platform_data3.min_vcore_override_mv = min_vcore_override_mv; } boot_vcore_mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail); if (boot_vcore_mv) { macallan_tegra_sdhci_platform_data0.boot_vcore_mv = boot_vcore_mv; tegra_sdhci_platform_data2.boot_vcore_mv = boot_vcore_mv; tegra_sdhci_platform_data3.boot_vcore_mv = boot_vcore_mv; } speedo = tegra_fuse_readl(FUSE_CORE_SPEEDO_0); tegra_sdhci_platform_data0.cpu_speedo = speedo; tegra_sdhci_platform_data2.cpu_speedo = speedo; tegra_sdhci_platform_data3.cpu_speedo = speedo; if ((tegra_sdhci_platform_data3.uhs_mask & MMC_MASK_HS200) && (!(tegra_sdhci_platform_data3.uhs_mask & MMC_UHS_MASK_DDR50))) tegra_sdhci_platform_data3.trim_delay = 0; platform_device_register(&tegra_sdhci_device3); platform_device_register(&tegra_sdhci_device2); platform_device_register(&tegra_sdhci_device0); #endif macallan_wifi_init(); return 0; }
static void tegra_xusb_read_usb_calib(void) { u32 usb_calib0 = tegra_fuse_readl(FUSE_SKU_USB_CALIB_0); pr_info("tegra_xusb_read_usb_calib: usb_calib0 = 0x%08x\n", usb_calib0); /* * read from usb_calib0 and pass to driver * set HS_CURR_LEVEL (PAD0) = usb_calib0[5:0] * set TERM_RANGE_ADJ = usb_calib0[10:7] * set HS_SQUELCH_LEVEL = usb_calib0[12:11] * set HS_IREF_CAP = usb_calib0[14:13] * set HS_CURR_LEVEL (PAD1) = usb_calib0[20:15] */ tegra_xusb_plat_data.hs_curr_level_pad0 = (usb_calib0 >> 0) & 0x3f; tegra_xusb_plat_data.hs_term_range_adj = (usb_calib0 >> 7) & 0xf; tegra_xusb_plat_data.hs_squelch_level = (usb_calib0 >> 11) & 0x3; tegra_xusb_plat_data.hs_iref_cap = (usb_calib0 >> 13) & 0x3; tegra_xusb_plat_data.hs_curr_level_pad1 = (usb_calib0 >> 15) & 0x3f; }
static void pluto_xusb_init(void) { int usb_port_owner_info = tegra_get_usb_port_owner_info(); if (usb_port_owner_info & UTMI1_PORT_OWNER_XUSB) { u32 usb_calib0 = tegra_fuse_readl(FUSE_SKU_USB_CALIB_0); /* * read from usb_calib0 and pass to driver * set HS_CURR_LEVEL = usb_calib0[5:0] * set TERM_RANGE_ADJ = usb_calib0[10:7] * set HS_IREF_CAP = usb_calib0[14:13] * set HS_SQUELCH_LEVEL = usb_calib0[12:11] */ xusb_padctl_data.hs_curr_level = (usb_calib0 >> 0) & 0x3f; xusb_padctl_data.hs_iref_cap = (usb_calib0 >> 13) & 0x3; xusb_padctl_data.hs_term_range_adj = (usb_calib0 >> 7) & 0xf; xusb_padctl_data.hs_squelch_level = (usb_calib0 >> 11) & 0x3; tegra_xhci_device.dev.platform_data = &xusb_padctl_data; platform_device_register(&tegra_xhci_device); }
static inline bool get_spare_fuse(int bit) { return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); }
void tegra_init_speedo_data(void) { int i; if (!tegra_platform_is_silicon()) { cpu_process_id = 0; core_process_id = 0; gpu_process_id = 0; cpu_speedo_id = 0; soc_speedo_id = 0; gpu_speedo_id = 0; package_id = -1; cpu_speedo_value = 1777; gpu_speedo_value = 2000; cpu_speedo_0_value = 0; cpu_speedo_1_value = 0; soc_speedo_0_value = 0; soc_speedo_1_value = 0; soc_speedo_2_value = 0; soc_iddq_value = 0; gpu_iddq_value = 0; return; } cpu_speedo_0_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_0); cpu_speedo_1_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_1); /* GPU Speedo is stored in CPU_SPEEDO_2 */ gpu_speedo_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_2); soc_speedo_0_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_0); soc_speedo_1_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_1); soc_speedo_2_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_2); cpu_iddq_value = tegra_fuse_readl(FUSE_CPU_IDDQ); soc_iddq_value = tegra_fuse_readl(FUSE_SOC_IDDQ); gpu_iddq_value = tegra_fuse_readl(FUSE_GPU_IDDQ); cpu_speedo_value = cpu_speedo_0_value; if (cpu_speedo_value == 0) { cpu_speedo_value = 2100; pr_warn("Tegra13: Warning: CPU Speedo value not fused. PLEASE FIX!!!!!!!!!!!\n"); pr_warn("Tegra13: Warning: PLEASE USE BOARD WITH FUSED SPEEDO VALUE !!!!\n"); } if (gpu_speedo_value == 0) { gpu_speedo_value = 2000; pr_warn("Tegra13: Warning: GPU Speedo value not fused. PLEASE FIX!!!!!!!!!!!\n"); pr_warn("Tegra13: Warning: PLEASE USE BOARD WITH FUSED SPEEDO VALUE !!!!\n"); } rev_sku_to_speedo_ids(tegra_revision, tegra_get_sku_id()); for (i = 0; i < GPU_PROCESS_CORNERS_NUM; i++) { if (gpu_speedo_value < gpu_process_speedos[threshold_index][i]) { break; } } gpu_process_id = i; for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) { if (cpu_speedo_value < cpu_process_speedos[threshold_index][i]) { break; } } cpu_process_id = i; for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) { if (soc_speedo_0_value < core_process_speedos[threshold_index][i]) { break; } } core_process_id = i; pr_info("Tegra13: CPU Speedo ID %d, Soc Speedo ID %d, Gpu Speedo ID %d\n", cpu_speedo_id, soc_speedo_id, gpu_speedo_id); pr_info("Tegra13: CPU Process ID %d,Soc Process ID %d,Gpu Process ID %d\n", cpu_process_id, core_process_id, gpu_process_id); pr_info("Tegra13: CPU Speedo value %d, Soc Speedo value %d, Gpu Speedo value %d\n", cpu_speedo_value, soc_speedo_0_value, gpu_speedo_value); }
void tegra_init_speedo_data(void) { int i; u32 tegra_sku_id; if (!tegra_platform_is_silicon()) { cpu_process_id = 0; core_process_id = 0; gpu_process_id = 0; cpu_speedo_id = 0; soc_speedo_id = 0; gpu_speedo_id = 0; package_id = -1; cpu_speedo_value = TEGRA21_CPU_SPEEDO; gpu_speedo_value = TEGRA21_GPU_SPEEDO; soc_speedo_value = TEGRA21_SOC_SPEEDO; cpu_speedo_0_value = 0; cpu_speedo_1_value = 0; soc_speedo_0_value = 0; soc_speedo_1_value = 0; soc_speedo_2_value = 0; soc_iddq_value = 0; gpu_iddq_value = 0; pr_info("Tegra21: CPU Speedo value %d, Soc Speedo value %d, Gpu Speedo value %d\n", cpu_speedo_value, soc_speedo_value, gpu_speedo_value); pr_info("Tegra21: CPU Speedo ID %d, Soc Speedo ID %d, Gpu Speedo ID %d\n", cpu_speedo_id, soc_speedo_id, gpu_speedo_id); pr_info("Tegra21: CPU Process ID %d,Soc Process ID %d,Gpu Process ID %d\n", cpu_process_id, core_process_id, gpu_process_id); return; } /* Read speedo/iddq fuses */ cpu_speedo_0_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_0); cpu_speedo_1_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_1); cpu_speedo_2_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_2); soc_speedo_0_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_0); soc_speedo_1_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_1); soc_speedo_2_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_2); cpu_iddq_value = tegra_fuse_readl(FUSE_CPU_IDDQ) * 4; soc_iddq_value = tegra_fuse_readl(FUSE_SOC_IDDQ) * 4; gpu_iddq_value = tegra_fuse_readl(FUSE_GPU_IDDQ) * 5; /* * Determine CPU, GPU, SOC speedo values depending on speedo fusing * revision. Note that GPU speedo value is fused in CPU_SPEEDO_2 */ speedo_rev = get_speedo_rev(); if (speedo_rev >= 3) { cpu_speedo_value = cpu_speedo_0_value; gpu_speedo_value = cpu_speedo_2_value; soc_speedo_value = soc_speedo_0_value; } else if (speedo_rev == 2) { cpu_speedo_value = (-1938 + (1095*cpu_speedo_0_value/100)) / 10; gpu_speedo_value = (-1662 + (1082*cpu_speedo_2_value/100)) / 10; soc_speedo_value = (-705 + (1037*soc_speedo_0_value/100)) / 10; } else { /* FIXME: do we need hard-coded IDDQ here? */ cpu_speedo_value = TEGRA21_CPU_SPEEDO; gpu_speedo_value = cpu_speedo_2_value - TEGRA21_GPU_SPEEDO_OFFS; soc_speedo_value = TEGRA21_SOC_SPEEDO; } if (cpu_speedo_value <= 0) { cpu_speedo_value = TEGRA21_CPU_SPEEDO; pr_warn("Tegra21: Warning: CPU Speedo value not fused. PLEASE FIX!!!!!!!!!!!\n"); pr_warn("Tegra21: Warning: PLEASE USE BOARD WITH FUSED SPEEDO VALUE !!!!\n"); } if (gpu_speedo_value <= 0) { gpu_speedo_value = TEGRA21_GPU_SPEEDO; pr_warn("Tegra21: Warning: GPU Speedo value not fused. PLEASE FIX!!!!!!!!!!!\n"); pr_warn("Tegra21: Warning: PLEASE USE BOARD WITH FUSED SPEEDO VALUE !!!!\n"); } if (soc_speedo_value <= 0) { soc_speedo_value = TEGRA21_SOC_SPEEDO; pr_warn("Tegra21: Warning: SOC Speedo value not fused. PLEASE FIX!!!!!!!!!!!\n"); pr_warn("Tegra21: Warning: PLEASE USE BOARD WITH FUSED SPEEDO VALUE !!!!\n"); } /* Map chip sku, rev, speedo values into speedo and process IDs */ tegra_sku_id = tegra_get_sku_id(); rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, speedo_rev); for (i = 0; i < GPU_PROCESS_CORNERS_NUM; i++) { if (gpu_speedo_value < gpu_process_speedos[threshold_index][i]) { break; } } gpu_process_id = i; for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) { if (cpu_speedo_value < cpu_process_speedos[threshold_index][i]) { break; } } cpu_process_id = i; for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) { if (soc_speedo_value < core_process_speedos[threshold_index][i]) { break; } } core_process_id = i; pr_info("Tegra21: Speedo/IDDQ fuse revision %d\n", speedo_rev); pr_info("Tegra21: CPU Speedo ID %d, Soc Speedo ID %d, Gpu Speedo ID %d\n", cpu_speedo_id, soc_speedo_id, gpu_speedo_id); pr_info("Tegra21: CPU Process ID %d, Soc Process ID %d, Gpu Process ID %d\n", cpu_process_id, core_process_id, gpu_process_id); pr_info("Tegra21: CPU Speedo value %d, Soc Speedo value %d, Gpu Speedo value %d\n", cpu_speedo_value, soc_speedo_value, gpu_speedo_value); pr_info("Tegra21: CPU IDDQ %d, Soc IDDQ %d, Gpu IDDQ %d\n", cpu_iddq_value, soc_iddq_value, gpu_iddq_value); }
unsigned int tegra_spare_fuse(int bit) { BUG_ON(bit < 0 || bit > 61); return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); }
int __init ardbeg_sdhci_init(void) { int nominal_core_mv; int min_vcore_override_mv; int boot_vcore_mv; u32 speedo; struct board_info board_info; nominal_core_mv = tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail); if (nominal_core_mv) { tegra_sdhci_platform_data0.nominal_vcore_mv = nominal_core_mv; tegra_sdhci_platform_data2.nominal_vcore_mv = nominal_core_mv; tegra_sdhci_platform_data3.nominal_vcore_mv = nominal_core_mv; } min_vcore_override_mv = tegra_dvfs_rail_get_override_floor(tegra_core_rail); if (min_vcore_override_mv) { tegra_sdhci_platform_data0.min_vcore_override_mv = min_vcore_override_mv; tegra_sdhci_platform_data2.min_vcore_override_mv = min_vcore_override_mv; tegra_sdhci_platform_data3.min_vcore_override_mv = min_vcore_override_mv; } boot_vcore_mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail); if (boot_vcore_mv) { tegra_sdhci_platform_data0.boot_vcore_mv = boot_vcore_mv; tegra_sdhci_platform_data2.boot_vcore_mv = boot_vcore_mv; tegra_sdhci_platform_data3.boot_vcore_mv = boot_vcore_mv; } if (of_machine_is_compatible("nvidia,laguna") || of_machine_is_compatible("nvidia,jetson-tk1")) tegra_sdhci_platform_data2.wp_gpio = ARDBEG_SD_WP; tegra_get_board_info(&board_info); if (board_info.board_id == BOARD_E1780) tegra_sdhci_platform_data2.max_clk_limit = 204000000; /* E1780 and E1784 are using interposer E1816, Due to this the * SDIO trace length got increased. So hard coding the drive * strength to type A for these boards to support 204 Mhz */ if ((board_info.board_id == BOARD_E1780) || (board_info.board_id == BOARD_E1784)) { tegra_sdhci_platform_data0.default_drv_type = MMC_SET_DRIVER_TYPE_A; } tegra_sdhci_platform_data0.max_clk_limit = 204000000; if (board_info.board_id == BOARD_E1781) tegra_sdhci_platform_data3.uhs_mask = MMC_MASK_HS200; if (board_info.board_id == BOARD_PM374 || board_info.board_id == BOARD_PM358 || board_info.board_id == BOARD_PM363 || board_info.board_id == BOARD_PM359) tegra_sdhci_platform_data0.disable_clock_gate = 1; /* * FIXME: Set max clk limit to 200MHz for SDMMC3 for PM375. * Requesting 208MHz results in getting 204MHz from PLL_P * and CRC errors are seen with same. */ if (board_info.board_id == BOARD_PM375) tegra_sdhci_platform_data2.max_clk_limit = 200000000; speedo = tegra_fuse_readl(FUSE_SOC_SPEEDO_0); tegra_sdhci_platform_data0.cpu_speedo = speedo; tegra_sdhci_platform_data2.cpu_speedo = speedo; tegra_sdhci_platform_data3.cpu_speedo = speedo; if (board_info.board_id == BOARD_E1991 || board_info.board_id == BOARD_E1971) { tegra_sdhci_platform_data0.uhs_mask = MMC_UHS_MASK_SDR50 | MMC_UHS_MASK_DDR50; tegra_sdhci_platform_data2.uhs_mask = MMC_UHS_MASK_SDR50; } if (board_info.board_id == BOARD_PM374 || board_info.board_id == BOARD_PM359) { tegra_sdhci_platform_data2.uhs_mask = MMC_UHS_MASK_SDR50; tegra_sdhci_platform_data0.uhs_mask = MMC_UHS_MASK_SDR50; tegra_sdhci_platform_data3.max_clk_limit = 200000000; tegra_sdhci_platform_data2.max_clk_limit = 204000000; } platform_device_register(&tegra_sdhci_device3); if (!is_uart_over_sd_enabled()) platform_device_register(&tegra_sdhci_device2); /* No wifi module for PM375 */ if (board_info.board_id != BOARD_PM359 && board_info.board_id != BOARD_PM375) { platform_device_register(&tegra_sdhci_device0); ardbeg_wifi_init(); } return 0; }