781 lines
22 KiB
C
781 lines
22 KiB
C
|
/*
|
||
|
* Copyright (C) 2012-2014 Apple Inc. All rights reserved.
|
||
|
*
|
||
|
* This document is the property of Apple Inc.
|
||
|
* It is considered confidential and proprietary.
|
||
|
*
|
||
|
* This document may not be reproduced or transmitted in any form,
|
||
|
* in whole or in part, without the express written permission of
|
||
|
* Apple Inc.
|
||
|
*/
|
||
|
|
||
|
#include <debug.h>
|
||
|
#include <platform.h>
|
||
|
#include <platform/soc/chipid.h>
|
||
|
#include <platform/soc/hwclocks.h>
|
||
|
|
||
|
#define CHIPID_VOLTAGE_FIXED 0
|
||
|
#define CHIPID_MODE_NONE 0
|
||
|
|
||
|
struct chipid_voltage_config {
|
||
|
uint32_t safe_voltage;
|
||
|
uint32_t mode;
|
||
|
};
|
||
|
|
||
|
#if SUB_PLATFORM_T7000 || SUB_PLATFORM_T7001
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
static struct chipid_voltage_config chipid_cpu_voltages[] = {
|
||
|
[CHIPID_CPU_VOLTAGE_BYPASS] = {1000, CHIPID_MODE_NONE},
|
||
|
[CHIPID_CPU_VOLTAGE_SECUREROM] = {1000, CHIPID_MODE_NONE},
|
||
|
[CHIPID_CPU_VOLTAGE_V0] = { 775, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V1] = { 800, 3},
|
||
|
[CHIPID_CPU_VOLTAGE_V2] = { 880, 4},
|
||
|
[CHIPID_CPU_VOLTAGE_V3] = { 995, 5},
|
||
|
#if !SUB_TARGET_N102
|
||
|
[CHIPID_CPU_VOLTAGE_V4] = {1125, 7},
|
||
|
#endif
|
||
|
#if SUB_TARGET_J96 || SUB_TARGET_J97
|
||
|
[CHIPID_CPU_VOLTAGE_V5] = {1195, 8},
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
static struct chipid_voltage_config chipid_soc_voltages[] = {
|
||
|
[CHIPID_SOC_VOLTAGE_BYPASS] = {950, CHIPID_MODE_NONE},
|
||
|
[CHIPID_SOC_VOLTAGE_SECUREROM] = {950, CHIPID_MODE_NONE},
|
||
|
[CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF] = {900, CHIPID_MODE_NONE},
|
||
|
[CHIPID_SOC_VOLTAGE_VMIN] = {900, 1},
|
||
|
[CHIPID_SOC_VOLTAGE_VNOM] = {950, 2},
|
||
|
};
|
||
|
|
||
|
static struct chipid_voltage_config chipid_gpu_voltages[] = {
|
||
|
[CHIPID_GPU_VOLTAGE_OFF] = { 0, CHIPID_MODE_NONE},
|
||
|
[CHIPID_GPU_VOLTAGE_V0] = { 900, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V0_DIDT] = { 900, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V1] = { 950, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V1_DIDT] = { 950, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V2] = {1050, 3},
|
||
|
[CHIPID_GPU_VOLTAGE_V2_DIDT] = {1050, 3},
|
||
|
#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D || SUB_TARGET_J96 || SUB_TARGET_J97
|
||
|
[CHIPID_GPU_VOLTAGE_V3] = {1050, 4},
|
||
|
[CHIPID_GPU_VOLTAGE_V3_DIDT] = {1050, 4},
|
||
|
#endif
|
||
|
#if SUB_TARGET_J96 || SUB_TARGET_J97
|
||
|
[CHIPID_GPU_VOLTAGE_V4] = {1010, 5},
|
||
|
[CHIPID_GPU_VOLTAGE_V4_DIDT] = {1010, 5},
|
||
|
[CHIPID_GPU_VOLTAGE_V5] = {}, //CHIPID_GPU_VOLTAGE_V5 not used on J96/J97
|
||
|
[CHIPID_GPU_VOLTAGE_V5_DIDT] = {},
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
static struct chipid_voltage_config chipid_sram_voltages[] = {
|
||
|
#if SUB_TARGET_N56 || SUB_TARGET_J42 || SUB_TARGET_J42D
|
||
|
[CHIPID_VOLTAGE_FIXED] = {970, 1},
|
||
|
#else
|
||
|
[CHIPID_VOLTAGE_FIXED] = {950, 1},
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
static struct chipid_voltage_config chipid_cpu_voltages[] = {
|
||
|
[CHIPID_CPU_VOLTAGE_BYPASS] = {1000, CHIPID_MODE_NONE},
|
||
|
[CHIPID_CPU_VOLTAGE_SECUREROM] = {1000, CHIPID_MODE_NONE},
|
||
|
[CHIPID_CPU_VOLTAGE_V0] = { 775, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V1] = { 800, 3},
|
||
|
[CHIPID_CPU_VOLTAGE_V2] = { 880, 4},
|
||
|
[CHIPID_CPU_VOLTAGE_V3] = { 980, 5},
|
||
|
[CHIPID_CPU_VOLTAGE_V4] = {1125, 7},
|
||
|
[CHIPID_CPU_VOLTAGE_V5] = {1250, 8},
|
||
|
[CHIPID_CPU_VOLTAGE_V6] = {1200, 9},
|
||
|
[CHIPID_CPU_VOLTAGE_V6_UNBINNED] = {1200, CHIPID_MODE_NONE},
|
||
|
};
|
||
|
|
||
|
static struct chipid_voltage_config chipid_sram_voltages[] = {
|
||
|
[CHIPID_CPU_VOLTAGE_BYPASS] = { 950, CHIPID_MODE_NONE},
|
||
|
[CHIPID_CPU_VOLTAGE_SECUREROM] = { 950, CHIPID_MODE_NONE},
|
||
|
[CHIPID_CPU_VOLTAGE_V0] = { 950, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V1] = { 950, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V2] = { 950, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V3] = { 950, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V4] = {1000, 1},
|
||
|
[CHIPID_CPU_VOLTAGE_V5] = {1000, 2},
|
||
|
[CHIPID_CPU_VOLTAGE_V6] = {1000, 2},
|
||
|
[CHIPID_CPU_VOLTAGE_V6_UNBINNED] = {1000, CHIPID_MODE_NONE},
|
||
|
};
|
||
|
|
||
|
// CHIPID_GPU_VOLTAGE_V4 / 600MHz is only used on T7000
|
||
|
static struct chipid_voltage_config chipid_gpu_voltages[] = {
|
||
|
[CHIPID_GPU_VOLTAGE_OFF] = { 0, CHIPID_MODE_NONE},
|
||
|
[CHIPID_GPU_VOLTAGE_V0] = { 900, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V0_DIDT] = { 900, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V1] = { 950, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V1_DIDT] = { 950, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V2] = {1050, 3},
|
||
|
[CHIPID_GPU_VOLTAGE_V2_DIDT] = {1050, 3},
|
||
|
[CHIPID_GPU_VOLTAGE_V3] = {1050, 4},
|
||
|
[CHIPID_GPU_VOLTAGE_V3_DIDT] = {1050, 4},
|
||
|
[CHIPID_GPU_VOLTAGE_V5] = {1100, 5},
|
||
|
[CHIPID_GPU_VOLTAGE_V5_DIDT] = {1100, 5},
|
||
|
};
|
||
|
|
||
|
static struct chipid_voltage_config chipid_gpu_sram_voltages[] = {
|
||
|
[CHIPID_GPU_VOLTAGE_OFF] = { 950, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V0] = { 950, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V0_DIDT] = { 950, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V1] = { 950, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V1_DIDT] = { 950, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V2] = {1050, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V2_DIDT] = {1050, 1},
|
||
|
[CHIPID_GPU_VOLTAGE_V3] = {1050, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V3_DIDT] = {1050, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V5] = {1050, 2},
|
||
|
[CHIPID_GPU_VOLTAGE_V5_DIDT] = {1050, 2},
|
||
|
};
|
||
|
|
||
|
static struct chipid_voltage_config chipid_soc_voltages[] = {
|
||
|
[CHIPID_VOLTAGE_FIXED] = {950, CHIPID_MODE_NONE},
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#define CHIP_REVISION_ALL 0xff
|
||
|
#define CHIP_ID_ALL 0x00
|
||
|
struct vol_adj_struct {
|
||
|
uint32_t index;
|
||
|
uint32_t chipid;
|
||
|
uint32_t chiprev;
|
||
|
uint32_t minimum_fuserev;
|
||
|
struct chipid_vol_adj vol_adj;
|
||
|
};
|
||
|
|
||
|
static struct vol_adj_struct vol_adj_cpu[] = {
|
||
|
// T7000 b0 and T7001 a0
|
||
|
{CHIPID_CPU_VOLTAGE_V0, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 31250}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V0, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 31250}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V0, 0x7001, CHIP_REVISION_A1, 0, {{ 0, 12500, 25000, 31250}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V1, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 25000}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V1, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 25000}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V1, 0x7001, CHIP_REVISION_A1, 0, {{ 0, 9380, 25000, 31250}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V2, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 25000}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V2, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 25000}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V3, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 12500, 25000, 25000}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V3, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 12500, 25000, 25000}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V4, 0x7000, CHIP_REVISION_B0, 0, {{ 12500, 12500, 12500, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V4, 0x7001, CHIP_REVISION_A0, 0, {{ 12500, 12500, 12500, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V5, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V5, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V6, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V6, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V6_UNBINNED, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V6_UNBINNED, 0x7001, CHIP_REVISION_A0, 0, {{ 0, 0, 0, 0}}},
|
||
|
|
||
|
// If not found in previous line, the following will be used, i.e. 7001 a1 and 7000 b1 will use it.
|
||
|
{CHIPID_CPU_VOLTAGE_V0, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 15630, 34380, 40630}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V1, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 12500, 25000, 31250}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V2, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 9380, 18750, 18750}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V3, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 6250, 12500, 12500}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V4, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V5, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V6, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_CPU_VOLTAGE_V6_UNBINNED, CHIP_ID_ALL, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}},
|
||
|
};
|
||
|
|
||
|
static struct vol_adj_struct vol_adj_soc[] = {
|
||
|
{CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_SOC_VOLTAGE_VMIN, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 9400, 18800, 18800}}},
|
||
|
{CHIPID_SOC_VOLTAGE_VNOM, 0x7000, CHIP_REVISION_B0, 0, {{ 0, 9400, 15600, 9400}}},
|
||
|
|
||
|
//If not found in previous line, the following will be used, i.e. 7000 b1 will use it.
|
||
|
{CHIPID_SOC_VOLTAGE_IBOOT_MEM_LOW_PERF, 0x7000, CHIP_REVISION_ALL, 0, {{ 0, 0, 0, 0}}},
|
||
|
{CHIPID_SOC_VOLTAGE_VMIN, 0x7000, CHIP_REVISION_ALL, 0, {{ 0, 12500, 28130, 28130}}},
|
||
|
{CHIPID_SOC_VOLTAGE_VNOM, 0x7000, CHIP_REVISION_ALL, 0, {{ 0, 9380, 21880, 21880}}},
|
||
|
|
||
|
};
|
||
|
|
||
|
static uint32_t chipid_get_bin_type(void)
|
||
|
{
|
||
|
// For Capri FUSE_REV is a combination of CFG_FUSE4[5:0] and bit 287/286 for J82/J99 applications
|
||
|
// Chip fuse286 fuse287
|
||
|
// 0x7000 0 0 N56/N61
|
||
|
// 0X7000 1 0 J42
|
||
|
// 0X7000 0 1 J96/J97/N102
|
||
|
// 0X7000 0 0 J81/J82
|
||
|
// 0x7001 1 0 J98/J99
|
||
|
return (rCFG_FUSE8 >> 30) & 0x3;
|
||
|
}
|
||
|
|
||
|
// Base Voltage = (Base Fuse + 1) * 25
|
||
|
static uint32_t chipid_get_base_voltage(void)
|
||
|
{
|
||
|
uint32_t voltage;
|
||
|
|
||
|
voltage = (((rCCC_EFUSE_REV >> 24) & 0x1F) + 1) * 25;
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
// <rdar://problem/16190886> Fiji B0: Binning information for parts with fuse revision 0x9 Fiji B0:(CoreOs)
|
||
|
if (chipid_get_fuse_revision() == 0x9)
|
||
|
voltage -= 25;
|
||
|
#endif
|
||
|
|
||
|
return voltage;
|
||
|
}
|
||
|
|
||
|
static uint32_t chipid_get_cpu_binfuse_for_mode(uint32_t mode)
|
||
|
{
|
||
|
uint32_t binfuse;
|
||
|
|
||
|
switch (mode) {
|
||
|
case 9:
|
||
|
binfuse = (rCCC_EFUSE_DVFM0 >> 0) & 0x7F;
|
||
|
break;
|
||
|
case 1:
|
||
|
binfuse = (rCCC_EFUSE_DVFM0 >> 8) & 0x7F;
|
||
|
break;
|
||
|
case 8:
|
||
|
#if SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_N102
|
||
|
if (chipid_get_bin_type() == 0x0) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
binfuse = (rCCC_EFUSE_DVFM0 >> 16) & 0x7F;
|
||
|
break;
|
||
|
case 3:
|
||
|
binfuse = (rCCC_EFUSE_DVFM0 >> 24) & 0x7F;
|
||
|
break;
|
||
|
case 4:
|
||
|
binfuse = (rCCC_EFUSE_DVFM1 >> 0) & 0x7F;
|
||
|
break;
|
||
|
case 5:
|
||
|
binfuse = (rCCC_EFUSE_DVFM1 >> 8) & 0x7F;
|
||
|
break;
|
||
|
case 6:
|
||
|
binfuse = (rCCC_EFUSE_DVFM1 >> 16) & 0x7F;
|
||
|
break;
|
||
|
case 7:
|
||
|
binfuse = (rCCC_EFUSE_DVFM1 >> 24) & 0x7F;
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unsupported CPU mode %d\n", mode);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return binfuse;
|
||
|
}
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
static uint32_t chipid_get_soc_binfuse_for_mode(uint32_t mode)
|
||
|
{
|
||
|
uint32_t binfuse;
|
||
|
|
||
|
switch (mode) {
|
||
|
case 1:
|
||
|
binfuse = (rCFG_FUSE7 >> 0) & 0x7F;
|
||
|
break;
|
||
|
case 2:
|
||
|
binfuse = (rCFG_FUSE7 >> 7) & 0x7F;
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unsupported SOC mode %d\n", mode);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return binfuse;
|
||
|
}
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
static uint32_t chipid_get_sram_binfuse_for_mode(uint32_t mode)
|
||
|
{
|
||
|
uint32_t binfuse;
|
||
|
|
||
|
switch (mode) {
|
||
|
case 1:
|
||
|
binfuse = (rCFG_FUSE7 >> 0) & 0x7F;
|
||
|
break;
|
||
|
case 2:
|
||
|
binfuse = (rCFG_FUSE7 >> 7) & 0x7F;
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unsupported SRAM mode %d\n", mode);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return binfuse;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static uint32_t chipid_get_gpu_binfuse_for_mode(uint32_t mode)
|
||
|
{
|
||
|
uint32_t binfuse;
|
||
|
|
||
|
switch (mode) {
|
||
|
case 1:
|
||
|
binfuse = (rCFG_FUSE7 >> 14) & 0x7F;
|
||
|
break;
|
||
|
case 2:
|
||
|
binfuse = (rCFG_FUSE7 >> 21) & 0x7F;
|
||
|
break;
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
case 3: // CFG[265:259]
|
||
|
binfuse = (rCFG_FUSE8 >> 3) & 0x7F;
|
||
|
break;
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
case 3: // CFG[258:252]
|
||
|
binfuse = (rCFG_FUSE7 >> 28) & 0xF;
|
||
|
binfuse |= (rCFG_FUSE8 << 4) & 0x70;
|
||
|
break;
|
||
|
#endif
|
||
|
case 4: // CFG[272:266]
|
||
|
binfuse = (rCFG_FUSE8 >> 10) & 0x7F;
|
||
|
break;
|
||
|
#if SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_N102
|
||
|
case 5: // CFG[279:273]
|
||
|
if (chipid_get_bin_type() == 0x0) {
|
||
|
return 0;
|
||
|
}
|
||
|
binfuse = (rCFG_FUSE8 >> (273 - 256)) & 0x7f;
|
||
|
break;
|
||
|
#else
|
||
|
case 5: // CFG[223:217]
|
||
|
binfuse = (rCFG_FUSE6 >> 25) & 0x7F;
|
||
|
break;
|
||
|
#endif
|
||
|
default:
|
||
|
panic("Unsupported GPU mode %d\n", mode);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return binfuse;
|
||
|
}
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
static uint32_t chipid_get_sram_binfuse_for_mode(uint32_t mode)
|
||
|
{
|
||
|
uint32_t binfuse;
|
||
|
|
||
|
switch (mode) {
|
||
|
case 1:
|
||
|
binfuse = (rCFG_FUSE7 >> 28) & 0xF;
|
||
|
binfuse |= (rCFG_FUSE8 << 4) & 0x70;
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unsupported SRAM mode %d\n", mode);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return binfuse;
|
||
|
}
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
static uint32_t chipid_get_soc_binfuse_for_mode(uint32_t mode)
|
||
|
{
|
||
|
uint32_t binfuse;
|
||
|
|
||
|
switch (mode) {
|
||
|
case 1:
|
||
|
binfuse = (rCFG_FUSE8 >> 3) & 0x7F;
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unsupported SOC mode %d\n", mode);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return binfuse;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static uint32_t chipid_get_cpu_bin_voltage(uint32_t volt_index)
|
||
|
{
|
||
|
uint32_t mode, binfuse;
|
||
|
|
||
|
mode = chipid_cpu_voltages[volt_index].mode;
|
||
|
|
||
|
// Return safe voltage if no binned voltage
|
||
|
if (mode == CHIPID_MODE_NONE)
|
||
|
return chipid_cpu_voltages[volt_index].safe_voltage;
|
||
|
|
||
|
binfuse = chipid_get_cpu_binfuse_for_mode(mode);
|
||
|
if (binfuse == 0)
|
||
|
return chipid_cpu_voltages[volt_index].safe_voltage;
|
||
|
#if SUB_TARGET_N102
|
||
|
if (volt_index == CHIPID_CPU_VOLTAGE_V0) {
|
||
|
// <rdar://problem/20056603> N102: Remove CPU P7 (1392 MHz) and lower CPU P1 voltage by 15mV
|
||
|
return (chipid_get_base_voltage() + binfuse * 5 - 15);
|
||
|
}
|
||
|
#endif
|
||
|
return (chipid_get_base_voltage() + binfuse * 5);
|
||
|
}
|
||
|
|
||
|
static uint32_t chipid_get_soc_bin_voltage(uint32_t volt_index)
|
||
|
{
|
||
|
uint32_t mode, binfuse;
|
||
|
|
||
|
mode = chipid_soc_voltages[volt_index].mode;
|
||
|
|
||
|
// Return safe voltage if no binned voltage
|
||
|
if (mode == CHIPID_MODE_NONE)
|
||
|
return chipid_soc_voltages[volt_index].safe_voltage;
|
||
|
|
||
|
binfuse = chipid_get_soc_binfuse_for_mode(mode);
|
||
|
|
||
|
return (chipid_get_base_voltage() + binfuse * 5);
|
||
|
}
|
||
|
|
||
|
static uint32_t chipid_get_gpu_bin_voltage(uint32_t volt_index)
|
||
|
{
|
||
|
uint32_t mode, binfuse;
|
||
|
|
||
|
mode = chipid_gpu_voltages[volt_index].mode;
|
||
|
|
||
|
// Return safe voltage if no binned voltage
|
||
|
if (mode == CHIPID_MODE_NONE)
|
||
|
return chipid_gpu_voltages[volt_index].safe_voltage;
|
||
|
|
||
|
binfuse = chipid_get_gpu_binfuse_for_mode(mode);
|
||
|
if (binfuse == 0)
|
||
|
return chipid_gpu_voltages[volt_index].safe_voltage;
|
||
|
|
||
|
return (chipid_get_base_voltage() + binfuse * 5);
|
||
|
}
|
||
|
|
||
|
static uint32_t chipid_get_sram_bin_voltage(uint32_t volt_index)
|
||
|
{
|
||
|
uint32_t mode, binfuse;
|
||
|
|
||
|
mode = chipid_sram_voltages[volt_index].mode;
|
||
|
|
||
|
// Return safe voltage if no binned voltage
|
||
|
if (mode == CHIPID_MODE_NONE)
|
||
|
return chipid_sram_voltages[volt_index].safe_voltage;
|
||
|
|
||
|
binfuse = chipid_get_sram_binfuse_for_mode(mode);
|
||
|
|
||
|
return (chipid_get_base_voltage() + binfuse * 5);
|
||
|
}
|
||
|
|
||
|
#if SUB_PLATFORM_T7001
|
||
|
static uint32_t chipid_get_gpu_sram_bin_voltage(uint32_t volt_index)
|
||
|
{
|
||
|
uint32_t mode, binfuse;
|
||
|
|
||
|
mode = chipid_gpu_sram_voltages[volt_index].mode;
|
||
|
|
||
|
// Return safe voltage if no binned voltage
|
||
|
if (mode == CHIPID_MODE_NONE)
|
||
|
return chipid_gpu_sram_voltages[volt_index].safe_voltage;
|
||
|
|
||
|
binfuse = chipid_get_sram_binfuse_for_mode(mode);
|
||
|
|
||
|
return (chipid_get_base_voltage() + binfuse * 5);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
bool chipid_get_current_production_mode(void)
|
||
|
{
|
||
|
return ((rCFG_FUSE0 >> 0) & 1) != 0;
|
||
|
}
|
||
|
|
||
|
bool chipid_get_raw_production_mode(void)
|
||
|
{
|
||
|
return ((rCFG_FUSE0_RAW >> 0) & 1) != 0;
|
||
|
}
|
||
|
|
||
|
void chipid_clear_production_mode(void)
|
||
|
{
|
||
|
rCFG_FUSE0 &= ~1;
|
||
|
}
|
||
|
|
||
|
bool chipid_get_secure_mode(void)
|
||
|
{
|
||
|
// demotion only applies to the SEP, so iBoot always reads
|
||
|
// the raw value for secure mode (<rdar://problem/15182573>)
|
||
|
return ((rCFG_FUSE0_RAW >> 1) & 1) != 0;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_security_domain(void)
|
||
|
{
|
||
|
return (rCFG_FUSE0 >> 2) & 3;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_board_id(void)
|
||
|
{
|
||
|
return (rCFG_FUSE0 >> 4) & 7;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_minimum_epoch(void)
|
||
|
{
|
||
|
return (rCFG_FUSE0 >> 9) & 0x7F;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_pid(void)
|
||
|
{
|
||
|
return (rCFG_FUSE0 >> 16) & 0x3;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_chip_id(void)
|
||
|
{
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
return 0x7000;
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
return 0x7001;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_chip_revision(void)
|
||
|
{
|
||
|
uint32_t chip_rev = (((rCFG_FUSE4 >> 19) & 0x7) << 4)
|
||
|
| (((rCFG_FUSE4 >> 16) & 0x7) << 0);
|
||
|
return chip_rev;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_osc_frequency(void)
|
||
|
{
|
||
|
return OSC_FREQ;
|
||
|
}
|
||
|
|
||
|
uint64_t chipid_get_ecid_id(void)
|
||
|
{
|
||
|
#if SUPPORT_FPGA
|
||
|
return (0x000012345678ABCDULL);
|
||
|
#else
|
||
|
return ((uint64_t)rECIDHI << 32) | rECIDLO;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
uint64_t chipid_get_die_id(void)
|
||
|
{
|
||
|
return ((uint64_t)rECIDHI << 32) | rECIDLO;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_soc_voltage(uint32_t index)
|
||
|
{
|
||
|
uint32_t soc_voltage;
|
||
|
|
||
|
#if SUB_PLATFORM_T7001
|
||
|
index = CHIPID_VOLTAGE_FIXED;
|
||
|
#endif
|
||
|
|
||
|
if (index >= sizeof(chipid_soc_voltages)/sizeof(chipid_soc_voltages[0]))
|
||
|
panic("Invalid SOC voltage index %d\n", index);
|
||
|
|
||
|
if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION)
|
||
|
soc_voltage = chipid_soc_voltages[index].safe_voltage;
|
||
|
else
|
||
|
soc_voltage = chipid_get_soc_bin_voltage(index);
|
||
|
|
||
|
return soc_voltage;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_cpu_voltage(uint32_t index)
|
||
|
{
|
||
|
uint32_t cpu_voltage;
|
||
|
|
||
|
if (index >= sizeof(chipid_cpu_voltages)/sizeof(chipid_cpu_voltages[0]))
|
||
|
panic("Invalid CPU voltage index %d\n", index);
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION)
|
||
|
cpu_voltage = chipid_cpu_voltages[index].safe_voltage;
|
||
|
else
|
||
|
cpu_voltage = chipid_get_cpu_bin_voltage(index);
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
if (chipid_get_fuse_revision() >= MINIMUM_FUSE_REVISION)
|
||
|
cpu_voltage = chipid_get_cpu_bin_voltage(index);
|
||
|
else
|
||
|
cpu_voltage = chipid_cpu_voltages[index].safe_voltage;
|
||
|
#endif
|
||
|
|
||
|
return cpu_voltage;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_ram_voltage(uint32_t index)
|
||
|
{
|
||
|
uint32_t sram_voltage;
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
index = CHIPID_VOLTAGE_FIXED;
|
||
|
#endif
|
||
|
|
||
|
if (index >= sizeof(chipid_sram_voltages)/sizeof(chipid_sram_voltages[0]))
|
||
|
panic("Invalid SRAM voltage index %d\n", index);
|
||
|
|
||
|
if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION)
|
||
|
sram_voltage = chipid_sram_voltages[index].safe_voltage;
|
||
|
else
|
||
|
sram_voltage = chipid_get_sram_bin_voltage(index);
|
||
|
|
||
|
return sram_voltage;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_gpu_ram_voltage(uint32_t index)
|
||
|
{
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
panic("GPU SRAM voltage not supported\n");
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
uint32_t gpu_sram_voltage;
|
||
|
|
||
|
if (index >= sizeof(chipid_gpu_sram_voltages)/sizeof(chipid_gpu_sram_voltages[0]))
|
||
|
panic("Invalid GPU SRAM voltage index %d\n", index);
|
||
|
|
||
|
if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION)
|
||
|
gpu_sram_voltage = chipid_gpu_sram_voltages[index].safe_voltage;
|
||
|
else
|
||
|
gpu_sram_voltage = chipid_get_gpu_sram_bin_voltage(index);
|
||
|
|
||
|
return gpu_sram_voltage;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_gpu_voltage(uint32_t index)
|
||
|
{
|
||
|
uint32_t gpu_voltage;
|
||
|
|
||
|
if (index >= sizeof(chipid_gpu_voltages)/sizeof(chipid_gpu_voltages[0]))
|
||
|
panic("Invalid GPU voltage index %d\n", index);
|
||
|
|
||
|
if (chipid_get_fuse_revision() < MINIMUM_FUSE_REVISION)
|
||
|
gpu_voltage = chipid_gpu_voltages[index].safe_voltage;
|
||
|
#if SUB_PLATFORM_T7001
|
||
|
else if ((index == CHIPID_GPU_VOLTAGE_V4 || index == CHIPID_GPU_VOLTAGE_V4_DIDT) &&
|
||
|
chipid_get_fuse_revision() < MINIMUM_BINNED_GPU_P6_REVISION)
|
||
|
gpu_voltage = chipid_get_gpu_bin_voltage(index - 1) + P6_VOL_OFFSET_FROM_P4_BINNING;
|
||
|
#endif
|
||
|
else
|
||
|
gpu_voltage = chipid_get_gpu_bin_voltage(index);
|
||
|
|
||
|
return gpu_voltage;
|
||
|
}
|
||
|
|
||
|
bool chipid_get_fuse_lock(void)
|
||
|
{
|
||
|
return (rCFG_FUSE1 & (1 << 31)) != 0;
|
||
|
}
|
||
|
|
||
|
void chipid_set_fuse_lock(bool locked)
|
||
|
{
|
||
|
if (locked) {
|
||
|
rCFG_FUSE1 |= (1 << 31);
|
||
|
asm("dsb sy");
|
||
|
if ((rCFG_FUSE1 & (1 << 31)) == 0) {
|
||
|
panic("Failed to lock fuses\n");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_soc_temp_sensor_trim(uint32_t sensor_index)
|
||
|
{
|
||
|
uint32_t trim_value = CFG_FUSE2_THERMAL_SEN(sensor_index);
|
||
|
return trim_value;
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_fuse_revision(void)
|
||
|
{
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
// For Fiji FUSE_REV is CFG_FUSE4[5:0]
|
||
|
#if SUB_TARGET_J96 || SUB_TARGET_J97 || SUB_TARGET_N102
|
||
|
if (chipid_get_bin_type() == 0x2) {// J96/J97/N102 binning
|
||
|
// Start at MINIMUM_FUSE_REVISION + 1 = 0x10, to avoid 0x9 fuse revision which has a specific workaround.
|
||
|
return MINIMUM_FUSE_REVISION + 1 + ((rCFG_FUSE4 >> 0) & 0x3f);
|
||
|
}
|
||
|
#endif
|
||
|
return (rCFG_FUSE4 >> 0) & 0x3f;
|
||
|
#elif SUB_PLATFORM_T7001
|
||
|
// For Capri FUSE_REV is a combination of CFG_FUSE4[5:0] and bit 287 for J82/J99 applications
|
||
|
return (((rCFG_FUSE4 >> 0) & 0x3f) | ((rCFG_FUSE8 >> 31) & 0x1) << 6);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
uint32_t chipid_get_total_rails_leakage()
|
||
|
{
|
||
|
// FIXME
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#if SUPPORT_FPGA
|
||
|
uint32_t chipid_get_fpga_block_instantiation(void)
|
||
|
{
|
||
|
// Hardware blocks instantiated.
|
||
|
uint32_t blocks = (rECID_FUSE7 >> 16) & 0xF;
|
||
|
uint32_t mask = FPGA_HAS_ALWAYS;
|
||
|
|
||
|
#if SUB_PLATFORM_T7000
|
||
|
switch (blocks) {
|
||
|
case 0x1: // INT2
|
||
|
case 0x2: // old "Fiji" endcoding in pre 06_xx_yy_zz bitstream releases
|
||
|
break;
|
||
|
case 0x3: // INT2 + pcie
|
||
|
mask |= FPGA_HAS_PCIE;
|
||
|
break;
|
||
|
case 0x8: // INT2 + VXD + AVE + JPEG + MEDIA
|
||
|
mask |= FPGA_HAS_VXD | FPGA_HAS_AVE | FPGA_HAS_JPEG | FPGA_HAS_MEDIA;
|
||
|
break;
|
||
|
case 0x9: // INT2 + DISP0 + DISP1 + MSR + JPEG + MEDIA
|
||
|
mask |= FPGA_HAS_DISP0 | FPGA_HAS_DISP1 | FPGA_HAS_MSR | FPGA_HAS_JPEG | FPGA_HAS_MEDIA;
|
||
|
break;
|
||
|
case 0xA: // INT2 + GFX
|
||
|
mask |= FPGA_HAS_GFX;
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unknown hardware block instantiation: 0x%x", blocks);
|
||
|
}
|
||
|
#elif SUB_PLATFORM_T7001 // No AVE on Capri FPGA
|
||
|
switch (blocks) {
|
||
|
case 0x1: // INT2
|
||
|
break;
|
||
|
case 0x8: // INT3 = INT2 + VXD + DISP0 + DISP1 + MEDIA + MSR + JPEG + PCIE
|
||
|
mask |= FPGA_HAS_VXD | FPGA_HAS_DISP0 | FPGA_HAS_DISP1 | FPGA_HAS_MEDIA | FPGA_HAS_MSR | FPGA_HAS_JPEG; // <rdar://problem/15014312> enable PCIE later
|
||
|
break;
|
||
|
case 0xA: // INT3 + GFX
|
||
|
mask |= FPGA_HAS_VXD | FPGA_HAS_DISP0 | FPGA_HAS_DISP1 | FPGA_HAS_MEDIA | FPGA_HAS_MSR | FPGA_HAS_JPEG | FPGA_HAS_GFX; // <rdar://problem/15014312> enable PCIE later
|
||
|
break;
|
||
|
default:
|
||
|
panic("Unknown hardware block instantiation: 0x%x", blocks);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return mask;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void chipid_get_vol_adj(enum chipid_vol_adj_type vol_adj_type, uint32_t index, struct chipid_vol_adj * vol_adj)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
uint32_t chipid = chipid_get_chip_id();
|
||
|
uint32_t chiprev = chipid_get_chip_revision();
|
||
|
uint32_t fuserev = chipid_get_fuse_revision();
|
||
|
switch (vol_adj_type) {
|
||
|
case CHIPID_VOL_ADJ_CPU:
|
||
|
for (i= 0; i < sizeof(vol_adj_cpu)/sizeof(vol_adj_cpu[0]); i++) {
|
||
|
if (vol_adj_cpu[i].index != index)
|
||
|
continue;
|
||
|
if ((vol_adj_cpu[i].chipid != CHIP_ID_ALL) && (vol_adj_cpu[i].chipid != chipid))
|
||
|
continue;
|
||
|
if ((vol_adj_cpu[i].chiprev != CHIP_REVISION_ALL) && (vol_adj_cpu[i].chiprev != chiprev))
|
||
|
continue;
|
||
|
if ((vol_adj_cpu[i]).minimum_fuserev > fuserev)
|
||
|
continue;
|
||
|
*vol_adj = vol_adj_cpu[i].vol_adj;
|
||
|
return;
|
||
|
}
|
||
|
panic("%s haven't found CPU index %d for chip %x rev 0x%x\n", __func__, index, chipid, chiprev);
|
||
|
break;
|
||
|
case CHIPID_VOL_ADJ_SOC:
|
||
|
for (i= 0; i < sizeof(vol_adj_soc)/sizeof(vol_adj_soc[0]); i++) {
|
||
|
if (vol_adj_soc[i].index != index)
|
||
|
continue;
|
||
|
if ((vol_adj_soc[i].chipid != CHIP_ID_ALL) && (vol_adj_soc[i].chipid != chipid))
|
||
|
continue;
|
||
|
if ((vol_adj_soc[i].chiprev != CHIP_REVISION_ALL) && (vol_adj_soc[i].chiprev != chiprev))
|
||
|
continue;
|
||
|
if ((vol_adj_soc[i]).minimum_fuserev > fuserev)
|
||
|
continue;
|
||
|
*vol_adj = vol_adj_soc[i].vol_adj;
|
||
|
return;
|
||
|
}
|
||
|
panic("%s haven't found SOC Index %d for chip %x rev 0x%x\n", __func__, index, chipid, chiprev);
|
||
|
break;
|
||
|
default:
|
||
|
panic("%s haven't found %d\n", __func__, index);
|
||
|
break;
|
||
|
}
|
||
|
}
|