[HTC Sensation] Jonny:
Ok, recently I have recieved several PM's asking for a more detailed explanation of why the Sensation runs at 1.2GHz and the XE at 1.5GHz.

My original explanation was dumbed down quite a bit so it would make sense to non-dev people :p

So anyway here is the full explanation:

It is all to do with the kernel and so for this example I will be using source from the kernel in the 3.33.401.153 ROM builds (curtosy of htcdev.com )

Before we start, lets just get 1 thing clear:

Common misconception No. 1 - The Sensation and Sensation XE have different kernels. - This is wrong, the Sensation and XE have EXACTLY THE SAME kernel (dont believe me? Check out the URL's of the download links to the source on htdev.com - they go to the same file).

Explanation of speed.

The speed at which the CPU runs at is determined by the file acpuclock-0x60.c in the kernel source and it contains several frequency tables, eg:

static struct clkctl_acpu_speed acpu_freq_tbl_1188mhz[] = {
{ {1, 1}, 192000, ACPU_PLL_8, 3, 1, 0, 0, L2(1), 812500, 0x03006000},
/* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
{ {0, 0}, MAX_AXI, ACPU_AFAB, 1, 0, 0, 0, L2(0), 875000, 0x03006000},
{ {1, 1}, 384000, ACPU_PLL_8, 3, 0, 0, 0, L2(1), 875000, 0x03006000},
{ {1, 1}, 432000, ACPU_SCPLL, 0, 0, 1, 0x08, L2(1), 887500, 0x03006000},
{ {1, 1}, 486000, ACPU_SCPLL, 0, 0, 1, 0x09, L2(2), 912500, 0x03006000},
{ {1, 1}, 540000, ACPU_SCPLL, 0, 0, 1, 0x0A, L2(3), 925000, 0x03006000},
{ {1, 1}, 594000, ACPU_SCPLL, 0, 0, 1, 0x0B, L2(4), 937500, 0x03006000},
{ {1, 1}, 648000, ACPU_SCPLL, 0, 0, 1, 0x0C, L2(5), 950000, 0x03006000},
{ {1, 1}, 702000, ACPU_SCPLL, 0, 0, 1, 0x0D, L2(6), 975000, 0x03006000},
{ {1, 1}, 756000, ACPU_SCPLL, 0, 0, 1, 0x0E, L2(7), 1000000, 0x03006000},
{ {1, 1}, 810000, ACPU_SCPLL, 0, 0, 1, 0x0F, L2(8), 1012500, 0x03006000},
{ {1, 1}, 864000, ACPU_SCPLL, 0, 0, 1, 0x10, L2(9), 1037500, 0x03006000},
{ {1, 1}, 918000, ACPU_SCPLL, 0, 0, 1, 0x11, L2(10), 1062500, 0x03006000},
{ {1, 1}, 972000, ACPU_SCPLL, 0, 0, 1, 0x12, L2(11), 1087500, 0x03006000},
{ {1, 1}, 1026000, ACPU_SCPLL, 0, 0, 1, 0x13, L2(12), 1125000, 0x03006000},
{ {1, 1}, 1080000, ACPU_SCPLL, 0, 0, 1, 0x14, L2(13), 1137500, 0x03006000},
{ {1, 1}, 1134000, ACPU_SCPLL, 0, 0, 1, 0x15, L2(14), 1162500, 0x03006000},
{ {1, 1}, 1188000, ACPU_SCPLL, 0, 0, 1, 0x16, L2(15), 1187500, 0x03006000},
{ {0, 0}, 0 },
};

/* SCPLL frequencies = 2 * 27 MHz * L_VAL */
static struct clkctl_acpu_speed acpu_freq_tbl_slow[] = {
{ {1, 1}, 192000, ACPU_PLL_8, 3, 1, 0, 0, L2(1), 800000, 0x03006000},
/* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
{ {0, 0}, MAX_AXI, ACPU_AFAB, 1, 0, 0, 0, L2(0), 825000, 0x03006000},
{ {1, 1}, 384000, ACPU_PLL_8, 3, 0, 0, 0, L2(1), 825000, 0x03006000},
{ {1, 1}, 432000, ACPU_SCPLL, 0, 0, 1, 0x08, L2(1), 850000, 0x03006000},
{ {1, 1}, 486000, ACPU_SCPLL, 0, 0, 1, 0x09, L2(2), 850000, 0x03006000},
{ {1, 1}, 540000, ACPU_SCPLL, 0, 0, 1, 0x0A, L2(3), 875000, 0x03006000},
{ {1, 1}, 594000, ACPU_SCPLL, 0, 0, 1, 0x0B, L2(4), 875000, 0x03006000},
{ {1, 1}, 648000, ACPU_SCPLL, 0, 0, 1, 0x0C, L2(5), 900000, 0x03006000},
{ {1, 1}, 702000, ACPU_SCPLL, 0, 0, 1, 0x0D, L2(6), 900000, 0x03006000},
{ {1, 1}, 756000, ACPU_SCPLL, 0, 0, 1, 0x0E, L2(7), 925000, 0x03006000},
{ {1, 1}, 810000, ACPU_SCPLL, 0, 0, 1, 0x0F, L2(8), 975000, 0x03006000},
{ {1, 1}, 864000, ACPU_SCPLL, 0, 0, 1, 0x10, L2(9), 975000, 0x03006000},
{ {1, 1}, 918000, ACPU_SCPLL, 0, 0, 1, 0x11, L2(10), 1000000, 0x03006000},
{ {1, 1}, 972000, ACPU_SCPLL, 0, 0, 1, 0x12, L2(11), 1025000, 0x03006000},
{ {1, 1}, 1026000, ACPU_SCPLL, 0, 0, 1, 0x13, L2(12), 1025000, 0x03006000},
{ {1, 1}, 1080000, ACPU_SCPLL, 0, 0, 1, 0x14, L2(13), 1050000, 0x03006000},
{ {1, 1}, 1134000, ACPU_SCPLL, 0, 0, 1, 0x15, L2(14), 1075000, 0x03006000},
{ {1, 1}, 1188000, ACPU_SCPLL, 0, 0, 1, 0x16, L2(15), 1100000, 0x03006000},
{ {1, 1}, 1242000, ACPU_SCPLL, 0, 0, 1, 0x17, L2(16), 1125000, 0x03006000},
{ {1, 1}, 1296000, ACPU_SCPLL, 0, 0, 1, 0x18, L2(17), 1150000, 0x03006000},
{ {1, 1}, 1350000, ACPU_SCPLL, 0, 0, 1, 0x19, L2(18), 1150000, 0x03006000},
{ {1, 1}, 1404000, ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1175000, 0x03006000},
{ {1, 1}, 1458000, ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1200000, 0x03006000},
{ {1, 1}, 1512000, ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1225000, 0x03006000},
{ {0, 0}, 0 },
};

/* SCPLL frequencies = 2 * 27 MHz * L_VAL */
static struct clkctl_acpu_speed acpu_freq_tbl_nom[] = {
{ {1, 1}, 192000, ACPU_PLL_8, 3, 1, 0, 0, L2(1), 800000, 0x03006000},
/* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
{ {0, 0}, MAX_AXI, ACPU_AFAB, 1, 0, 0, 0, L2(0), 825000, 0x03006000},
{ {1, 1}, 384000, ACPU_PLL_8, 3, 0, 0, 0, L2(1), 825000, 0x03006000},
{ {1, 1}, 432000, ACPU_SCPLL, 0, 0, 1, 0x08, L2(1), 850000, 0x03006000},
{ {1, 1}, 486000, ACPU_SCPLL, 0, 0, 1, 0x09, L2(2), 850000, 0x03006000},
{ {1, 1}, 540000, ACPU_SCPLL, 0, 0, 1, 0x0A, L2(3), 875000, 0x03006000},
{ {1, 1}, 594000, ACPU_SCPLL, 0, 0, 1, 0x0B, L2(4), 875000, 0x03006000},
{ {1, 1}, 648000, ACPU_SCPLL, 0, 0, 1, 0x0C, L2(5), 900000, 0x03006000},
{ {1, 1}, 702000, ACPU_SCPLL, 0, 0, 1, 0x0D, L2(6), 900000, 0x03006000},
{ {1, 1}, 756000, ACPU_SCPLL, 0, 0, 1, 0x0E, L2(7), 925000, 0x03006000},
{ {1, 1}, 810000, ACPU_SCPLL, 0, 0, 1, 0x0F, L2(8), 950000, 0x03006000},
{ {1, 1}, 864000, ACPU_SCPLL, 0, 0, 1, 0x10, L2(9), 975000, 0x03006000},
{ {1, 1}, 918000, ACPU_SCPLL, 0, 0, 1, 0x11, L2(10), 975000, 0x03006000},
{ {1, 1}, 972000, ACPU_SCPLL, 0, 0, 1, 0x12, L2(11), 1000000, 0x03006000},
{ {1, 1}, 1026000, ACPU_SCPLL, 0, 0, 1, 0x13, L2(12), 1000000, 0x03006000},
{ {1, 1}, 1080000, ACPU_SCPLL, 0, 0, 1, 0x14, L2(13), 1025000, 0x03006000},
{ {1, 1}, 1134000, ACPU_SCPLL, 0, 0, 1, 0x15, L2(14), 1025000, 0x03006000},
{ {1, 1}, 1188000, ACPU_SCPLL, 0, 0, 1, 0x16, L2(15), 1050000, 0x03006000},
{ {1, 1}, 1242000, ACPU_SCPLL, 0, 0, 1, 0x17, L2(16), 1075000, 0x03006000},
{ {1, 1}, 1296000, ACPU_SCPLL, 0, 0, 1, 0x18, L2(17), 1100000, 0x03006000},
{ {1, 1}, 1350000, ACPU_SCPLL, 0, 0, 1, 0x19, L2(18), 1125000, 0x03006000},
{ {1, 1}, 1404000, ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1150000, 0x03006000},
{ {1, 1}, 1458000, ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1150000, 0x03006000},
{ {1, 1}, 1512000, ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1175000, 0x03006000},
{ {0, 0}, 0 },
};

/* SCPLL frequencies = 2 * 27 MHz * L_VAL */
static struct clkctl_acpu_speed acpu_freq_tbl_fast[] = {
{ {1, 1}, 192000, ACPU_PLL_8, 3, 1, 0, 0, L2(1), 800000, 0x03006000},
/* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
{ {0, 0}, MAX_AXI, ACPU_AFAB, 1, 0, 0, 0, L2(0), 825000, 0x03006000},
{ {1, 1}, 384000, ACPU_PLL_8, 3, 0, 0, 0, L2(1), 825000, 0x03006000},
{ {1, 1}, 432000, ACPU_SCPLL, 0, 0, 1, 0x08, L2(1), 850000, 0x03006000},
{ {1, 1}, 486000, ACPU_SCPLL, 0, 0, 1, 0x09, L2(2), 850000, 0x03006000},
{ {1, 1}, 540000, ACPU_SCPLL, 0, 0, 1, 0x0A, L2(3), 875000, 0x03006000},
{ {1, 1}, 594000, ACPU_SCPLL, 0, 0, 1, 0x0B, L2(4), 875000, 0x03006000},
{ {1, 1}, 648000, ACPU_SCPLL, 0, 0, 1, 0x0C, L2(5), 900000, 0x03006000},
{ {1, 1}, 702000, ACPU_SCPLL, 0, 0, 1, 0x0D, L2(6), 900000, 0x03006000},
{ {1, 1}, 756000, ACPU_SCPLL, 0, 0, 1, 0x0E, L2(7), 925000, 0x03006000},
{ {1, 1}, 810000, ACPU_SCPLL, 0, 0, 1, 0x0F, L2(8), 925000, 0x03006000},
{ {1, 1}, 864000, ACPU_SCPLL, 0, 0, 1, 0x10, L2(9), 950000, 0x03006000},
{ {1, 1}, 918000, ACPU_SCPLL, 0, 0, 1, 0x11, L2(10), 950000, 0x03006000},
{ {1, 1}, 972000, ACPU_SCPLL, 0, 0, 1, 0x12, L2(11), 950000, 0x03006000},
{ {1, 1}, 1026000, ACPU_SCPLL, 0, 0, 1, 0x13, L2(12), 975000, 0x03006000},
{ {1, 1}, 1080000, ACPU_SCPLL, 0, 0, 1, 0x14, L2(13), 1000000, 0x03006000},
{ {1, 1}, 1134000, ACPU_SCPLL, 0, 0, 1, 0x15, L2(14), 1000000, 0x03006000},
{ {1, 1}, 1188000, ACPU_SCPLL, 0, 0, 1, 0x16, L2(15), 1025000, 0x03006000},
{ {1, 1}, 1242000, ACPU_SCPLL, 0, 0, 1, 0x17, L2(16), 1050000, 0x03006000},
{ {1, 1}, 1296000, ACPU_SCPLL, 0, 0, 1, 0x18, L2(17), 1075000, 0x03006000},
{ {1, 1}, 1350000, ACPU_SCPLL, 0, 0, 1, 0x19, L2(18), 1100000, 0x03006000},
{ {1, 1}, 1404000, ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1100000, 0x03006000},
{ {1, 1}, 1458000, ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1100000, 0x03006000},
{ {1, 1}, 1512000, ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1125000, 0x03006000},
{ {0, 0}, 0 },
};

Now you see there are different max speeds in those tables, one is for the XE (with 1512000 as the last value) and one for Sensation (with 1188000 as the last value).

So what determines which frequency table to use?

The below part of the code does:

static unsigned int __init select_freq_plan(void)
{
uint32_t pte_efuse, speed_bin, pvs, max_khz;
struct clkctl_acpu_speed *f;

pte_efuse = readl_relaxed(QFPROM_PTE_EFUSE_ADDR);

speed_bin = pte_efuse & 0xF;
if (speed_bin == 0xF)
speed_bin = (pte_efuse >> 4) & 0xF;

if (speed_bin == 0x1) {
max_khz = 1512000;
pvs = (pte_efuse >> 10) & 0x7;
if (pvs == 0x7)
pvs = (pte_efuse >> 13) & 0x7;

switch (pvs) {
case 0x0:
case 0x7:
acpu_freq_tbl = acpu_freq_tbl_slow;
pr_info("ACPU PVS: Slow\n");
break;
case 0x1:
acpu_freq_tbl = acpu_freq_tbl_nom;
pr_info("ACPU PVS: Nominal\n");
break;
case 0x3:
acpu_freq_tbl = acpu_freq_tbl_fast;
pr_info("ACPU PVS: Fast\n");
break;
default:
acpu_freq_tbl = acpu_freq_tbl_slow;
pr_warn("ACPU PVS: Unknown. Defaulting to slow.\n");
break;
}
} else {
max_khz = 1188000;
acpu_freq_tbl = acpu_freq_tbl_1188mhz;
}

/* Truncate the table based to max_khz. */
for (f = acpu_freq_tbl; f->acpuclk_khz != 0; f++) {
if (f->acpuclk_khz > max_khz) {
f->acpuclk_khz = 0;
break;
}
}
f--;
pr_info("Max ACPU freq: %u KHz\n", f->acpuclk_khz);

return f->acpuclk_khz;
}

As you can see, it is all determined by the hex value that speed_bin returns, if it returns 0x1 then the kernel uses the XE frequency table with a max_khz value of max_khz = 1512000; , anything else and it uses the normal Sensation table with a max_khz value of max_khz = 1188000; My guess is that speed_bin checks the Model ID of the phone in use (XE has a 1 instead of a 0 at the end of its MID).

So there you have it, hope you guys found this informative. Any questions, feel free to ask them below :)