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

cpu-imx5.c (3065B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
      4 *
      5 * This file contains the CPU initialization code.
      6 */
      7
      8#include <linux/types.h>
      9#include <linux/kernel.h>
     10#include <linux/init.h>
     11#include <linux/module.h>
     12#include <linux/io.h>
     13#include <linux/of.h>
     14#include <linux/of_address.h>
     15
     16#include "hardware.h"
     17#include "common.h"
     18
     19static int mx5_cpu_rev = -1;
     20
     21#define IIM_SREV 0x24
     22
     23static u32 imx5_read_srev_reg(const char *compat)
     24{
     25	void __iomem *iim_base;
     26	struct device_node *np;
     27	u32 srev;
     28
     29	np = of_find_compatible_node(NULL, NULL, compat);
     30	iim_base = of_iomap(np, 0);
     31	WARN_ON(!iim_base);
     32
     33	srev = readl(iim_base + IIM_SREV) & 0xff;
     34
     35	iounmap(iim_base);
     36
     37	return srev;
     38}
     39
     40static int get_mx51_srev(void)
     41{
     42	u32 rev = imx5_read_srev_reg("fsl,imx51-iim");
     43
     44	switch (rev) {
     45	case 0x0:
     46		return IMX_CHIP_REVISION_2_0;
     47	case 0x10:
     48		return IMX_CHIP_REVISION_3_0;
     49	default:
     50		return IMX_CHIP_REVISION_UNKNOWN;
     51	}
     52}
     53
     54/*
     55 * Returns:
     56 *	the silicon revision of the cpu
     57 */
     58int mx51_revision(void)
     59{
     60	if (mx5_cpu_rev == -1)
     61		mx5_cpu_rev = get_mx51_srev();
     62
     63	return mx5_cpu_rev;
     64}
     65EXPORT_SYMBOL(mx51_revision);
     66
     67#ifdef CONFIG_NEON
     68
     69/*
     70 * All versions of the silicon before Rev. 3 have broken NEON implementations.
     71 * Dependent on link order - so the assumption is that vfp_init is called
     72 * before us.
     73 */
     74int __init mx51_neon_fixup(void)
     75{
     76	if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
     77			(elf_hwcap & HWCAP_NEON)) {
     78		elf_hwcap &= ~HWCAP_NEON;
     79		pr_info("Turning off NEON support, detected broken NEON implementation\n");
     80	}
     81	return 0;
     82}
     83
     84#endif
     85
     86static int get_mx53_srev(void)
     87{
     88	u32 rev = imx5_read_srev_reg("fsl,imx53-iim");
     89
     90	switch (rev) {
     91	case 0x0:
     92		return IMX_CHIP_REVISION_1_0;
     93	case 0x2:
     94		return IMX_CHIP_REVISION_2_0;
     95	case 0x3:
     96		return IMX_CHIP_REVISION_2_1;
     97	default:
     98		return IMX_CHIP_REVISION_UNKNOWN;
     99	}
    100}
    101
    102/*
    103 * Returns:
    104 *	the silicon revision of the cpu
    105 */
    106int mx53_revision(void)
    107{
    108	if (mx5_cpu_rev == -1)
    109		mx5_cpu_rev = get_mx53_srev();
    110
    111	return mx5_cpu_rev;
    112}
    113EXPORT_SYMBOL(mx53_revision);
    114
    115#define ARM_GPC		0x4
    116#define DBGEN		BIT(16)
    117
    118/*
    119 * This enables the DBGEN bit in ARM_GPC register, which is
    120 * required for accessing some performance counter features.
    121 * Technically it is only required while perf is used, but to
    122 * keep the source code simple we just enable it all the time
    123 * when the kernel configuration allows using the feature.
    124 */
    125void __init imx5_pmu_init(void)
    126{
    127	void __iomem *tigerp_base;
    128	struct device_node *np;
    129	u32 gpc;
    130
    131	if (!IS_ENABLED(CONFIG_ARM_PMU))
    132		return;
    133
    134	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a8-pmu");
    135	if (!np)
    136		return;
    137
    138	if (!of_property_read_bool(np, "secure-reg-access"))
    139		goto exit;
    140
    141	of_node_put(np);
    142
    143	np = of_find_compatible_node(NULL, NULL, "fsl,imx51-tigerp");
    144	if (!np)
    145		return;
    146
    147	tigerp_base = of_iomap(np, 0);
    148	if (!tigerp_base)
    149		goto exit;
    150
    151	gpc = readl_relaxed(tigerp_base + ARM_GPC);
    152	gpc |= DBGEN;
    153	writel_relaxed(gpc, tigerp_base + ARM_GPC);
    154	iounmap(tigerp_base);
    155exit:
    156	of_node_put(np);
    157
    158}