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 
12 static 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 	unsigned int i;
17 
18 	emc->timings = memremap(rmem->base, rmem->size, MEMREMAP_WB);
19 	if (!emc->timings) {
20 		dev_err(dev, "failed to map EMC table\n");
21 		return -ENOMEM;
22 	}
23 
24 	emc->num_timings = 0;
25 
26 	for (i = 0; i < TEGRA_EMC_MAX_FREQS; i++) {
27 		if (emc->timings[i].revision == 0)
28 			break;
29 
30 		emc->num_timings++;
31 	}
32 
33 	return 0;
34 }
35 
36 static void tegra210_emc_table_device_release(struct reserved_mem *rmem,
37 					      struct device *dev)
38 {
39 	struct tegra210_emc *emc = dev_get_drvdata(dev);
40 
41 	memunmap(emc->timings);
42 }
43 
44 static const struct reserved_mem_ops tegra210_emc_table_ops = {
45 	.device_init = tegra210_emc_table_device_init,
46 	.device_release = tegra210_emc_table_device_release,
47 };
48 
49 static int tegra210_emc_table_init(struct reserved_mem *rmem)
50 {
51 	pr_debug("Tegra210 EMC table at %pa, size %lu bytes\n", &rmem->base,
52 		 (unsigned long)rmem->size);
53 
54 	rmem->ops = &tegra210_emc_table_ops;
55 
56 	return 0;
57 }
58 RESERVEDMEM_OF_DECLARE(tegra210_emc_table, "nvidia,tegra210-emc-table",
59 		       tegra210_emc_table_init);
60