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

tegra210-emc-table.c (2101B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.
      4 */
      5
      6#include <linux/of_reserved_mem.h>
      7
      8#include "tegra210-emc.h"
      9
     10#define TEGRA_EMC_MAX_FREQS		16
     11
     12static int tegra210_emc_table_device_init(struct reserved_mem *rmem,
     13					  struct device *dev)
     14{
     15	struct tegra210_emc *emc = dev_get_drvdata(dev);
     16	struct tegra210_emc_timing *timings;
     17	unsigned int i, count = 0;
     18
     19	timings = memremap(rmem->base, rmem->size, MEMREMAP_WB);
     20	if (!timings) {
     21		dev_err(dev, "failed to map EMC table\n");
     22		return -ENOMEM;
     23	}
     24
     25	count = 0;
     26
     27	for (i = 0; i < TEGRA_EMC_MAX_FREQS; i++) {
     28		if (timings[i].revision == 0)
     29			break;
     30
     31		count++;
     32	}
     33
     34	/* only the nominal and derated tables are expected */
     35	if (emc->derated) {
     36		dev_warn(dev, "excess EMC table '%s'\n", rmem->name);
     37		goto out;
     38	}
     39
     40	if (emc->nominal) {
     41		if (count != emc->num_timings) {
     42			dev_warn(dev, "%u derated vs. %u nominal entries\n",
     43				 count, emc->num_timings);
     44			memunmap(timings);
     45			return -EINVAL;
     46		}
     47
     48		emc->derated = timings;
     49	} else {
     50		emc->num_timings = count;
     51		emc->nominal = timings;
     52	}
     53
     54out:
     55	/* keep track of which table this is */
     56	rmem->priv = timings;
     57
     58	return 0;
     59}
     60
     61static void tegra210_emc_table_device_release(struct reserved_mem *rmem,
     62					      struct device *dev)
     63{
     64	struct tegra210_emc_timing *timings = rmem->priv;
     65	struct tegra210_emc *emc = dev_get_drvdata(dev);
     66
     67	if ((emc->nominal && timings != emc->nominal) &&
     68	    (emc->derated && timings != emc->derated))
     69		dev_warn(dev, "trying to release unassigned EMC table '%s'\n",
     70			 rmem->name);
     71
     72	memunmap(timings);
     73}
     74
     75static const struct reserved_mem_ops tegra210_emc_table_ops = {
     76	.device_init = tegra210_emc_table_device_init,
     77	.device_release = tegra210_emc_table_device_release,
     78};
     79
     80static int tegra210_emc_table_init(struct reserved_mem *rmem)
     81{
     82	pr_debug("Tegra210 EMC table at %pa, size %lu bytes\n", &rmem->base,
     83		 (unsigned long)rmem->size);
     84
     85	rmem->ops = &tegra210_emc_table_ops;
     86
     87	return 0;
     88}
     89RESERVEDMEM_OF_DECLARE(tegra210_emc_table, "nvidia,tegra210-emc-table",
     90		       tegra210_emc_table_init);