common.c (5d8dfaa71d87f742c53309b95cb6a8b274119027) common.c (66209e6fbd564f1bb3c69248423e4b761904a943)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#define dev_fmt(fmt) "tegra-soc: " fmt
7
8#include <linux/clk.h>
9#include <linux/device.h>
10#include <linux/export.h>
11#include <linux/of.h>
12#include <linux/pm_opp.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#define dev_fmt(fmt) "tegra-soc: " fmt
7
8#include <linux/clk.h>
9#include <linux/device.h>
10#include <linux/export.h>
11#include <linux/of.h>
12#include <linux/pm_opp.h>
13#include <linux/pm_runtime.h>
13
14#include <soc/tegra/common.h>
15#include <soc/tegra/fuse.h>
16
17static const struct of_device_id tegra_machine_match[] = {
18 { .compatible = "nvidia,tegra20", },
19 { .compatible = "nvidia,tegra30", },
20 { .compatible = "nvidia,tegra114", },

--- 17 unchanged lines hidden (view full) ---

38
39 return match != NULL;
40}
41
42static int tegra_core_dev_init_opp_state(struct device *dev)
43{
44 unsigned long rate;
45 struct clk *clk;
14
15#include <soc/tegra/common.h>
16#include <soc/tegra/fuse.h>
17
18static const struct of_device_id tegra_machine_match[] = {
19 { .compatible = "nvidia,tegra20", },
20 { .compatible = "nvidia,tegra30", },
21 { .compatible = "nvidia,tegra114", },

--- 17 unchanged lines hidden (view full) ---

39
40 return match != NULL;
41}
42
43static int tegra_core_dev_init_opp_state(struct device *dev)
44{
45 unsigned long rate;
46 struct clk *clk;
47 bool rpm_enabled;
46 int err;
47
48 clk = devm_clk_get(dev, NULL);
49 if (IS_ERR(clk)) {
50 dev_err(dev, "failed to get clk: %pe\n", clk);
51 return PTR_ERR(clk);
52 }
53
54 rate = clk_get_rate(clk);
55 if (!rate) {
56 dev_err(dev, "failed to get clk rate\n");
57 return -EINVAL;
58 }
59
48 int err;
49
50 clk = devm_clk_get(dev, NULL);
51 if (IS_ERR(clk)) {
52 dev_err(dev, "failed to get clk: %pe\n", clk);
53 return PTR_ERR(clk);
54 }
55
56 rate = clk_get_rate(clk);
57 if (!rate) {
58 dev_err(dev, "failed to get clk rate\n");
59 return -EINVAL;
60 }
61
62 /*
63 * Runtime PM of the device must be enabled in order to set up
64 * GENPD's performance properly because GENPD core checks whether
65 * device is suspended and this check doesn't work while RPM is
66 * disabled. This makes sure the OPP vote below gets cached in
67 * GENPD for the device. Instead, the vote is done the next time
68 * the device gets runtime resumed.
69 */
70 rpm_enabled = pm_runtime_enabled(dev);
71 if (!rpm_enabled)
72 pm_runtime_enable(dev);
73
74 /* should never happen in practice */
75 if (!pm_runtime_enabled(dev)) {
76 dev_WARN(dev, "failed to enable runtime PM\n");
77 pm_runtime_disable(dev);
78 return -EINVAL;
79 }
80
60 /* first dummy rate-setting initializes voltage vote */
61 err = dev_pm_opp_set_rate(dev, rate);
81 /* first dummy rate-setting initializes voltage vote */
82 err = dev_pm_opp_set_rate(dev, rate);
83
84 if (!rpm_enabled)
85 pm_runtime_disable(dev);
86
62 if (err) {
63 dev_err(dev, "failed to initialize OPP clock: %d\n", err);
64 return err;
65 }
66
67 return 0;
68}
69

--- 36 unchanged lines hidden (view full) ---

106 }
107
108 /*
109 * Older device-trees have an empty OPP table, we will get
110 * -ENODEV from devm_pm_opp_of_add_table() in this case.
111 */
112 err = devm_pm_opp_of_add_table(dev);
113 if (err) {
87 if (err) {
88 dev_err(dev, "failed to initialize OPP clock: %d\n", err);
89 return err;
90 }
91
92 return 0;
93}
94

--- 36 unchanged lines hidden (view full) ---

131 }
132
133 /*
134 * Older device-trees have an empty OPP table, we will get
135 * -ENODEV from devm_pm_opp_of_add_table() in this case.
136 */
137 err = devm_pm_opp_of_add_table(dev);
138 if (err) {
114 if (err == -ENODEV)
115 dev_err_once(dev, "OPP table not found, please update device-tree\n");
116 else
139 if (err != -ENODEV)
117 dev_err(dev, "failed to add OPP table: %d\n", err);
118
119 return err;
120 }
121
122 if (params->init_state) {
123 err = tegra_core_dev_init_opp_state(dev);
124 if (err)
125 return err;
126 }
127
128 return 0;
129}
130EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);
140 dev_err(dev, "failed to add OPP table: %d\n", err);
141
142 return err;
143 }
144
145 if (params->init_state) {
146 err = tegra_core_dev_init_opp_state(dev);
147 if (err)
148 return err;
149 }
150
151 return 0;
152}
153EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);