cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

speedo-tegra30.c (6808B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2012-2014, NVIDIA CORPORATION.  All rights reserved.
      4 */
      5
      6#include <linux/bug.h>
      7#include <linux/device.h>
      8#include <linux/kernel.h>
      9
     10#include <soc/tegra/fuse.h>
     11
     12#include "fuse.h"
     13
     14#define SOC_PROCESS_CORNERS	1
     15#define CPU_PROCESS_CORNERS	6
     16
     17#define FUSE_SPEEDO_CALIB_0	0x14
     18#define FUSE_PACKAGE_INFO	0XFC
     19#define FUSE_TEST_PROG_VER	0X28
     20
     21#define G_SPEEDO_BIT_MINUS1	58
     22#define G_SPEEDO_BIT_MINUS1_R	59
     23#define G_SPEEDO_BIT_MINUS2	60
     24#define G_SPEEDO_BIT_MINUS2_R	61
     25#define LP_SPEEDO_BIT_MINUS1	62
     26#define LP_SPEEDO_BIT_MINUS1_R	63
     27#define LP_SPEEDO_BIT_MINUS2	64
     28#define LP_SPEEDO_BIT_MINUS2_R	65
     29
     30enum {
     31	THRESHOLD_INDEX_0,
     32	THRESHOLD_INDEX_1,
     33	THRESHOLD_INDEX_2,
     34	THRESHOLD_INDEX_3,
     35	THRESHOLD_INDEX_4,
     36	THRESHOLD_INDEX_5,
     37	THRESHOLD_INDEX_6,
     38	THRESHOLD_INDEX_7,
     39	THRESHOLD_INDEX_8,
     40	THRESHOLD_INDEX_9,
     41	THRESHOLD_INDEX_10,
     42	THRESHOLD_INDEX_11,
     43	THRESHOLD_INDEX_COUNT,
     44};
     45
     46static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
     47	{180},
     48	{170},
     49	{195},
     50	{180},
     51	{168},
     52	{192},
     53	{180},
     54	{170},
     55	{195},
     56	{180},
     57	{180},
     58	{180},
     59};
     60
     61static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
     62	{306, 338, 360, 376, UINT_MAX},
     63	{295, 336, 358, 375, UINT_MAX},
     64	{325, 325, 358, 375, UINT_MAX},
     65	{325, 325, 358, 375, UINT_MAX},
     66	{292, 324, 348, 364, UINT_MAX},
     67	{324, 324, 348, 364, UINT_MAX},
     68	{324, 324, 348, 364, UINT_MAX},
     69	{295, 336, 358, 375, UINT_MAX},
     70	{358, 358, 358, 358, 397, UINT_MAX},
     71	{364, 364, 364, 364, 397, UINT_MAX},
     72	{295, 336, 358, 375, 391, UINT_MAX},
     73	{295, 336, 358, 375, 391, UINT_MAX},
     74};
     75
     76static int threshold_index __initdata;
     77
     78static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
     79{
     80	u32 reg;
     81	int ate_ver;
     82	int bit_minus1;
     83	int bit_minus2;
     84
     85	reg = tegra_fuse_read_early(FUSE_SPEEDO_CALIB_0);
     86
     87	*speedo_lp = (reg & 0xFFFF) * 4;
     88	*speedo_g = ((reg >> 16) & 0xFFFF) * 4;
     89
     90	ate_ver = tegra_fuse_read_early(FUSE_TEST_PROG_VER);
     91	pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
     92
     93	if (ate_ver >= 26) {
     94		bit_minus1 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1);
     95		bit_minus1 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1_R);
     96		bit_minus2 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2);
     97		bit_minus2 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2_R);
     98		*speedo_lp |= (bit_minus1 << 1) | bit_minus2;
     99
    100		bit_minus1 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1);
    101		bit_minus1 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1_R);
    102		bit_minus2 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2);
    103		bit_minus2 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2_R);
    104		*speedo_g |= (bit_minus1 << 1) | bit_minus2;
    105	} else {
    106		*speedo_lp |= 0x3;
    107		*speedo_g |= 0x3;
    108	}
    109}
    110
    111static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info)
    112{
    113	int package_id = tegra_fuse_read_early(FUSE_PACKAGE_INFO) & 0x0F;
    114
    115	switch (sku_info->revision) {
    116	case TEGRA_REVISION_A01:
    117		sku_info->cpu_speedo_id = 0;
    118		sku_info->soc_speedo_id = 0;
    119		threshold_index = THRESHOLD_INDEX_0;
    120		break;
    121	case TEGRA_REVISION_A02:
    122	case TEGRA_REVISION_A03:
    123		switch (sku_info->sku_id) {
    124		case 0x87:
    125		case 0x82:
    126			sku_info->cpu_speedo_id = 1;
    127			sku_info->soc_speedo_id = 1;
    128			threshold_index = THRESHOLD_INDEX_1;
    129			break;
    130		case 0x81:
    131			switch (package_id) {
    132			case 1:
    133				sku_info->cpu_speedo_id = 2;
    134				sku_info->soc_speedo_id = 2;
    135				threshold_index = THRESHOLD_INDEX_2;
    136				break;
    137			case 2:
    138				sku_info->cpu_speedo_id = 4;
    139				sku_info->soc_speedo_id = 1;
    140				threshold_index = THRESHOLD_INDEX_7;
    141				break;
    142			default:
    143				pr_err("Tegra Unknown pkg %d\n", package_id);
    144				break;
    145			}
    146			break;
    147		case 0x80:
    148			switch (package_id) {
    149			case 1:
    150				sku_info->cpu_speedo_id = 5;
    151				sku_info->soc_speedo_id = 2;
    152				threshold_index = THRESHOLD_INDEX_8;
    153				break;
    154			case 2:
    155				sku_info->cpu_speedo_id = 6;
    156				sku_info->soc_speedo_id = 2;
    157				threshold_index = THRESHOLD_INDEX_9;
    158				break;
    159			default:
    160				pr_err("Tegra Unknown pkg %d\n", package_id);
    161				break;
    162			}
    163			break;
    164		case 0x83:
    165			switch (package_id) {
    166			case 1:
    167				sku_info->cpu_speedo_id = 7;
    168				sku_info->soc_speedo_id = 1;
    169				threshold_index = THRESHOLD_INDEX_10;
    170				break;
    171			case 2:
    172				sku_info->cpu_speedo_id = 3;
    173				sku_info->soc_speedo_id = 2;
    174				threshold_index = THRESHOLD_INDEX_3;
    175				break;
    176			default:
    177				pr_err("Tegra Unknown pkg %d\n", package_id);
    178				break;
    179			}
    180			break;
    181		case 0x8F:
    182			sku_info->cpu_speedo_id = 8;
    183			sku_info->soc_speedo_id = 1;
    184			threshold_index = THRESHOLD_INDEX_11;
    185			break;
    186		case 0x08:
    187			sku_info->cpu_speedo_id = 1;
    188			sku_info->soc_speedo_id = 1;
    189			threshold_index = THRESHOLD_INDEX_4;
    190			break;
    191		case 0x02:
    192			sku_info->cpu_speedo_id = 2;
    193			sku_info->soc_speedo_id = 2;
    194			threshold_index = THRESHOLD_INDEX_5;
    195			break;
    196		case 0x04:
    197			sku_info->cpu_speedo_id = 3;
    198			sku_info->soc_speedo_id = 2;
    199			threshold_index = THRESHOLD_INDEX_6;
    200			break;
    201		case 0:
    202			switch (package_id) {
    203			case 1:
    204				sku_info->cpu_speedo_id = 2;
    205				sku_info->soc_speedo_id = 2;
    206				threshold_index = THRESHOLD_INDEX_2;
    207				break;
    208			case 2:
    209				sku_info->cpu_speedo_id = 3;
    210				sku_info->soc_speedo_id = 2;
    211				threshold_index = THRESHOLD_INDEX_3;
    212				break;
    213			default:
    214				pr_err("Tegra Unknown pkg %d\n", package_id);
    215				break;
    216			}
    217			break;
    218		default:
    219			pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id);
    220			sku_info->cpu_speedo_id = 0;
    221			sku_info->soc_speedo_id = 0;
    222			threshold_index = THRESHOLD_INDEX_0;
    223			break;
    224		}
    225		break;
    226	default:
    227		pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision);
    228		sku_info->cpu_speedo_id = 0;
    229		sku_info->soc_speedo_id = 0;
    230		threshold_index = THRESHOLD_INDEX_0;
    231		break;
    232	}
    233}
    234
    235void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info)
    236{
    237	u32 cpu_speedo_val;
    238	u32 soc_speedo_val;
    239	int i;
    240
    241	BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
    242			THRESHOLD_INDEX_COUNT);
    243	BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
    244			THRESHOLD_INDEX_COUNT);
    245
    246
    247	rev_sku_to_speedo_ids(sku_info);
    248	fuse_speedo_calib(&cpu_speedo_val, &soc_speedo_val);
    249	pr_debug("Tegra CPU speedo value %u\n", cpu_speedo_val);
    250	pr_debug("Tegra Core speedo value %u\n", soc_speedo_val);
    251
    252	for (i = 0; i < CPU_PROCESS_CORNERS; i++) {
    253		if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
    254			break;
    255	}
    256	sku_info->cpu_process_id = i - 1;
    257
    258	if (sku_info->cpu_process_id == -1) {
    259		pr_warn("Tegra CPU speedo value %3d out of range",
    260			 cpu_speedo_val);
    261		sku_info->cpu_process_id = 0;
    262		sku_info->cpu_speedo_id = 1;
    263	}
    264
    265	for (i = 0; i < SOC_PROCESS_CORNERS; i++) {
    266		if (soc_speedo_val < soc_process_speedos[threshold_index][i])
    267			break;
    268	}
    269	sku_info->soc_process_id = i - 1;
    270
    271	if (sku_info->soc_process_id == -1) {
    272		pr_warn("Tegra SoC speedo value %3d out of range",
    273			soc_speedo_val);
    274		sku_info->soc_process_id = 0;
    275		sku_info->soc_speedo_id = 1;
    276	}
    277}