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

tegra-apbmisc.c (4919B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
      4 */
      5
      6#include <linux/export.h>
      7#include <linux/kernel.h>
      8#include <linux/of.h>
      9#include <linux/of_address.h>
     10#include <linux/io.h>
     11
     12#include <soc/tegra/fuse.h>
     13#include <soc/tegra/common.h>
     14
     15#include "fuse.h"
     16
     17#define FUSE_SKU_INFO	0x10
     18
     19#define PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT	4
     20#define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG	\
     21	(0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT)
     22#define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT	\
     23	(0x3 << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT)
     24
     25static bool long_ram_code;
     26static u32 strapping;
     27static u32 chipid;
     28
     29u32 tegra_read_chipid(void)
     30{
     31	WARN(!chipid, "Tegra APB MISC not yet available\n");
     32
     33	return chipid;
     34}
     35
     36u8 tegra_get_chip_id(void)
     37{
     38	return (tegra_read_chipid() >> 8) & 0xff;
     39}
     40
     41u8 tegra_get_major_rev(void)
     42{
     43	return (tegra_read_chipid() >> 4) & 0xf;
     44}
     45
     46u8 tegra_get_minor_rev(void)
     47{
     48	return (tegra_read_chipid() >> 16) & 0xf;
     49}
     50
     51u8 tegra_get_platform(void)
     52{
     53	return (tegra_read_chipid() >> 20) & 0xf;
     54}
     55
     56bool tegra_is_silicon(void)
     57{
     58	switch (tegra_get_chip_id()) {
     59	case TEGRA194:
     60	case TEGRA234:
     61		if (tegra_get_platform() == 0)
     62			return true;
     63
     64		return false;
     65	}
     66
     67	/*
     68	 * Chips prior to Tegra194 have a different way of determining whether
     69	 * they are silicon or not. Since we never supported simulation on the
     70	 * older Tegra chips, don't bother extracting the information and just
     71	 * report that we're running on silicon.
     72	 */
     73	return true;
     74}
     75
     76u32 tegra_read_straps(void)
     77{
     78	WARN(!chipid, "Tegra ABP MISC not yet available\n");
     79
     80	return strapping;
     81}
     82
     83u32 tegra_read_ram_code(void)
     84{
     85	u32 straps = tegra_read_straps();
     86
     87	if (long_ram_code)
     88		straps &= PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG;
     89	else
     90		straps &= PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT;
     91
     92	return straps >> PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT;
     93}
     94EXPORT_SYMBOL_GPL(tegra_read_ram_code);
     95
     96static const struct of_device_id apbmisc_match[] __initconst = {
     97	{ .compatible = "nvidia,tegra20-apbmisc", },
     98	{ .compatible = "nvidia,tegra186-misc", },
     99	{ .compatible = "nvidia,tegra194-misc", },
    100	{ .compatible = "nvidia,tegra234-misc", },
    101	{},
    102};
    103
    104void __init tegra_init_revision(void)
    105{
    106	u8 chip_id, minor_rev;
    107
    108	chip_id = tegra_get_chip_id();
    109	minor_rev = tegra_get_minor_rev();
    110
    111	switch (minor_rev) {
    112	case 1:
    113		tegra_sku_info.revision = TEGRA_REVISION_A01;
    114		break;
    115	case 2:
    116		tegra_sku_info.revision = TEGRA_REVISION_A02;
    117		break;
    118	case 3:
    119		if (chip_id == TEGRA20 && (tegra_fuse_read_spare(18) ||
    120					   tegra_fuse_read_spare(19)))
    121			tegra_sku_info.revision = TEGRA_REVISION_A03p;
    122		else
    123			tegra_sku_info.revision = TEGRA_REVISION_A03;
    124		break;
    125	case 4:
    126		tegra_sku_info.revision = TEGRA_REVISION_A04;
    127		break;
    128	default:
    129		tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN;
    130	}
    131
    132	tegra_sku_info.sku_id = tegra_fuse_read_early(FUSE_SKU_INFO);
    133}
    134
    135void __init tegra_init_apbmisc(void)
    136{
    137	void __iomem *apbmisc_base, *strapping_base;
    138	struct resource apbmisc, straps;
    139	struct device_node *np;
    140
    141	np = of_find_matching_node(NULL, apbmisc_match);
    142	if (!np) {
    143		/*
    144		 * Fall back to legacy initialization for 32-bit ARM only. All
    145		 * 64-bit ARM device tree files for Tegra are required to have
    146		 * an APBMISC node.
    147		 *
    148		 * This is for backwards-compatibility with old device trees
    149		 * that didn't contain an APBMISC node.
    150		 */
    151		if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) {
    152			/* APBMISC registers (chip revision, ...) */
    153			apbmisc.start = 0x70000800;
    154			apbmisc.end = 0x70000863;
    155			apbmisc.flags = IORESOURCE_MEM;
    156
    157			/* strapping options */
    158			if (of_machine_is_compatible("nvidia,tegra124")) {
    159				straps.start = 0x7000e864;
    160				straps.end = 0x7000e867;
    161			} else {
    162				straps.start = 0x70000008;
    163				straps.end = 0x7000000b;
    164			}
    165
    166			straps.flags = IORESOURCE_MEM;
    167
    168			pr_warn("Using APBMISC region %pR\n", &apbmisc);
    169			pr_warn("Using strapping options registers %pR\n",
    170				&straps);
    171		} else {
    172			/*
    173			 * At this point we're not running on Tegra, so play
    174			 * nice with multi-platform kernels.
    175			 */
    176			return;
    177		}
    178	} else {
    179		/*
    180		 * Extract information from the device tree if we've found a
    181		 * matching node.
    182		 */
    183		if (of_address_to_resource(np, 0, &apbmisc) < 0) {
    184			pr_err("failed to get APBMISC registers\n");
    185			return;
    186		}
    187
    188		if (of_address_to_resource(np, 1, &straps) < 0) {
    189			pr_err("failed to get strapping options registers\n");
    190			return;
    191		}
    192	}
    193
    194	apbmisc_base = ioremap(apbmisc.start, resource_size(&apbmisc));
    195	if (!apbmisc_base) {
    196		pr_err("failed to map APBMISC registers\n");
    197	} else {
    198		chipid = readl_relaxed(apbmisc_base + 4);
    199		iounmap(apbmisc_base);
    200	}
    201
    202	strapping_base = ioremap(straps.start, resource_size(&straps));
    203	if (!strapping_base) {
    204		pr_err("failed to map strapping options registers\n");
    205	} else {
    206		strapping = readl_relaxed(strapping_base);
    207		iounmap(strapping_base);
    208	}
    209
    210	long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code");
    211}