blob: c801e871b39706cb568251c2ba3f3c3c7ba7377e
1 | /* |
2 | * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; if not, write to the Free Software Foundation, Inc., |
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | * |
18 | * Description: |
19 | */ |
20 | #include <linux/clk.h> |
21 | #include <linux/of_address.h> |
22 | #include <linux/of_platform.h> |
23 | #include <linux/pm_runtime.h> |
24 | |
25 | #include "aml_vcodec_dec_pm.h" |
26 | #include "aml_vcodec_util.h" |
27 | //#include "aml_vpu.h" |
28 | |
29 | int aml_vcodec_init_dec_pm(struct aml_vcodec_dev *amldev) |
30 | { |
31 | struct device_node *node; |
32 | struct platform_device *pdev; |
33 | struct aml_vcodec_pm *pm; |
34 | int ret = 0; |
35 | |
36 | pdev = amldev->plat_dev; |
37 | pm = &amldev->pm; |
38 | pm->amldev = amldev; |
39 | node = of_parse_phandle(pdev->dev.of_node, "larb", 0); |
40 | if (!node) { |
41 | aml_v4l2_err("of_parse_phandle larb fail!"); |
42 | return -1; |
43 | } |
44 | |
45 | pdev = of_find_device_by_node(node); |
46 | if (WARN_ON(!pdev)) { |
47 | of_node_put(node); |
48 | return -1; |
49 | } |
50 | pm->larbvdec = &pdev->dev; |
51 | pdev = amldev->plat_dev; |
52 | pm->dev = &pdev->dev; |
53 | |
54 | pm->vcodecpll = devm_clk_get(&pdev->dev, "vcodecpll"); |
55 | if (IS_ERR(pm->vcodecpll)) { |
56 | aml_v4l2_err("devm_clk_get vcodecpll fail"); |
57 | ret = PTR_ERR(pm->vcodecpll); |
58 | } |
59 | |
60 | pm->univpll_d2 = devm_clk_get(&pdev->dev, "univpll_d2"); |
61 | if (IS_ERR(pm->univpll_d2)) { |
62 | aml_v4l2_err("devm_clk_get univpll_d2 fail"); |
63 | ret = PTR_ERR(pm->univpll_d2); |
64 | } |
65 | |
66 | pm->clk_cci400_sel = devm_clk_get(&pdev->dev, "clk_cci400_sel"); |
67 | if (IS_ERR(pm->clk_cci400_sel)) { |
68 | aml_v4l2_err("devm_clk_get clk_cci400_sel fail"); |
69 | ret = PTR_ERR(pm->clk_cci400_sel); |
70 | } |
71 | |
72 | pm->vdec_sel = devm_clk_get(&pdev->dev, "vdec_sel"); |
73 | if (IS_ERR(pm->vdec_sel)) { |
74 | aml_v4l2_err("devm_clk_get vdec_sel fail"); |
75 | ret = PTR_ERR(pm->vdec_sel); |
76 | } |
77 | |
78 | pm->vdecpll = devm_clk_get(&pdev->dev, "vdecpll"); |
79 | if (IS_ERR(pm->vdecpll)) { |
80 | aml_v4l2_err("devm_clk_get vdecpll fail"); |
81 | ret = PTR_ERR(pm->vdecpll); |
82 | } |
83 | |
84 | pm->vencpll = devm_clk_get(&pdev->dev, "vencpll"); |
85 | if (IS_ERR(pm->vencpll)) { |
86 | aml_v4l2_err("devm_clk_get vencpll fail"); |
87 | ret = PTR_ERR(pm->vencpll); |
88 | } |
89 | |
90 | pm->venc_lt_sel = devm_clk_get(&pdev->dev, "venc_lt_sel"); |
91 | if (IS_ERR(pm->venc_lt_sel)) { |
92 | aml_v4l2_err("devm_clk_get venc_lt_sel fail"); |
93 | ret = PTR_ERR(pm->venc_lt_sel); |
94 | } |
95 | |
96 | pm->vdec_bus_clk_src = devm_clk_get(&pdev->dev, "vdec_bus_clk_src"); |
97 | if (IS_ERR(pm->vdec_bus_clk_src)) { |
98 | aml_v4l2_err("devm_clk_get vdec_bus_clk_src"); |
99 | ret = PTR_ERR(pm->vdec_bus_clk_src); |
100 | } |
101 | |
102 | pm_runtime_enable(&pdev->dev); |
103 | |
104 | return ret; |
105 | } |
106 | |
107 | void aml_vcodec_release_dec_pm(struct aml_vcodec_dev *dev) |
108 | { |
109 | pm_runtime_disable(dev->pm.dev); |
110 | } |
111 | |
112 | void aml_vcodec_dec_pw_on(struct aml_vcodec_pm *pm) |
113 | { |
114 | int ret; |
115 | |
116 | ret = pm_runtime_get_sync(pm->dev); |
117 | if (ret) |
118 | aml_v4l2_err("pm_runtime_get_sync fail %d", ret); |
119 | } |
120 | |
121 | void aml_vcodec_dec_pw_off(struct aml_vcodec_pm *pm) |
122 | { |
123 | int ret; |
124 | |
125 | ret = pm_runtime_put_sync(pm->dev); |
126 | if (ret) |
127 | aml_v4l2_err("pm_runtime_put_sync fail %d", ret); |
128 | } |
129 | |
130 | void aml_vcodec_dec_clock_on(struct aml_vcodec_pm *pm) |
131 | { |
132 | int ret; |
133 | |
134 | ret = clk_set_rate(pm->vcodecpll, 1482 * 1000000); |
135 | if (ret) |
136 | aml_v4l2_err("clk_set_rate vcodecpll fail %d", ret); |
137 | |
138 | ret = clk_set_rate(pm->vencpll, 800 * 1000000); |
139 | if (ret) |
140 | aml_v4l2_err("clk_set_rate vencpll fail %d", ret); |
141 | |
142 | ret = clk_prepare_enable(pm->vcodecpll); |
143 | if (ret) |
144 | aml_v4l2_err("clk_prepare_enable vcodecpll fail %d", ret); |
145 | |
146 | ret = clk_prepare_enable(pm->vencpll); |
147 | if (ret) |
148 | aml_v4l2_err("clk_prepare_enable vencpll fail %d", ret); |
149 | |
150 | ret = clk_prepare_enable(pm->vdec_bus_clk_src); |
151 | if (ret) |
152 | aml_v4l2_err("clk_prepare_enable vdec_bus_clk_src fail %d", |
153 | ret); |
154 | |
155 | ret = clk_prepare_enable(pm->venc_lt_sel); |
156 | if (ret) |
157 | aml_v4l2_err("clk_prepare_enable venc_lt_sel fail %d", ret); |
158 | |
159 | ret = clk_set_parent(pm->venc_lt_sel, pm->vdec_bus_clk_src); |
160 | if (ret) |
161 | aml_v4l2_err("clk_set_parent venc_lt_sel vdec_bus_clk_src fail %d", |
162 | ret); |
163 | |
164 | ret = clk_prepare_enable(pm->univpll_d2); |
165 | if (ret) |
166 | aml_v4l2_err("clk_prepare_enable univpll_d2 fail %d", ret); |
167 | |
168 | ret = clk_prepare_enable(pm->clk_cci400_sel); |
169 | if (ret) |
170 | aml_v4l2_err("clk_prepare_enable clk_cci400_sel fail %d", ret); |
171 | |
172 | ret = clk_set_parent(pm->clk_cci400_sel, pm->univpll_d2); |
173 | if (ret) |
174 | aml_v4l2_err("clk_set_parent clk_cci400_sel univpll_d2 fail %d", |
175 | ret); |
176 | |
177 | ret = clk_prepare_enable(pm->vdecpll); |
178 | if (ret) |
179 | aml_v4l2_err("clk_prepare_enable vdecpll fail %d", ret); |
180 | |
181 | ret = clk_prepare_enable(pm->vdec_sel); |
182 | if (ret) |
183 | aml_v4l2_err("clk_prepare_enable vdec_sel fail %d", ret); |
184 | |
185 | ret = clk_set_parent(pm->vdec_sel, pm->vdecpll); |
186 | if (ret) |
187 | aml_v4l2_err("clk_set_parent vdec_sel vdecpll fail %d", ret); |
188 | |
189 | //ret = aml_smi_larb_get(pm->larbvdec); |
190 | if (ret) |
191 | aml_v4l2_err("aml_smi_larb_get larbvdec fail %d", ret); |
192 | |
193 | } |
194 | |
195 | void aml_vcodec_dec_clock_off(struct aml_vcodec_pm *pm) |
196 | { |
197 | //aml_smi_larb_put(pm->larbvdec); |
198 | clk_disable_unprepare(pm->vdec_sel); |
199 | clk_disable_unprepare(pm->vdecpll); |
200 | clk_disable_unprepare(pm->univpll_d2); |
201 | clk_disable_unprepare(pm->clk_cci400_sel); |
202 | clk_disable_unprepare(pm->venc_lt_sel); |
203 | clk_disable_unprepare(pm->vdec_bus_clk_src); |
204 | clk_disable_unprepare(pm->vencpll); |
205 | clk_disable_unprepare(pm->vcodecpll); |
206 | } |
207 |