]> Git Repo - J-linux.git/blob - drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
Merge tag 'trace-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[J-linux.git] / drivers / media / platform / mtk-vcodec / mtk_vcodec_enc_pm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: Tiffany Lin <[email protected]>
5 */
6
7 #include <linux/clk.h>
8 #include <linux/of_address.h>
9 #include <linux/of_platform.h>
10 #include <linux/pm_runtime.h>
11 #include <soc/mediatek/smi.h>
12
13 #include "mtk_vcodec_enc_pm.h"
14 #include "mtk_vcodec_util.h"
15
16 int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
17 {
18         struct device_node *node;
19         struct platform_device *pdev;
20         struct mtk_vcodec_pm *pm;
21         struct mtk_vcodec_clk *enc_clk;
22         struct mtk_vcodec_clk_info *clk_info;
23         int ret = 0, i = 0;
24         struct device *dev;
25
26         pdev = mtkdev->plat_dev;
27         pm = &mtkdev->pm;
28         memset(pm, 0, sizeof(struct mtk_vcodec_pm));
29         pm->mtkdev = mtkdev;
30         pm->dev = &pdev->dev;
31         dev = &pdev->dev;
32         enc_clk = &pm->venc_clk;
33
34         node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
35         if (!node) {
36                 mtk_v4l2_err("no mediatek,larb found");
37                 return -ENODEV;
38         }
39         pdev = of_find_device_by_node(node);
40         of_node_put(node);
41         if (!pdev) {
42                 mtk_v4l2_err("no mediatek,larb device found");
43                 return -ENODEV;
44         }
45         pm->larbvenc = &pdev->dev;
46         pdev = mtkdev->plat_dev;
47         pm->dev = &pdev->dev;
48
49         enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
50                 "clock-names");
51         if (enc_clk->clk_num > 0) {
52                 enc_clk->clk_info = devm_kcalloc(&pdev->dev,
53                         enc_clk->clk_num, sizeof(*clk_info),
54                         GFP_KERNEL);
55                 if (!enc_clk->clk_info) {
56                         ret = -ENOMEM;
57                         goto put_larbvenc;
58                 }
59         } else {
60                 mtk_v4l2_err("Failed to get venc clock count");
61                 ret = -EINVAL;
62                 goto put_larbvenc;
63         }
64
65         for (i = 0; i < enc_clk->clk_num; i++) {
66                 clk_info = &enc_clk->clk_info[i];
67                 ret = of_property_read_string_index(pdev->dev.of_node,
68                         "clock-names", i, &clk_info->clk_name);
69                 if (ret) {
70                         mtk_v4l2_err("venc failed to get clk name %d", i);
71                         goto put_larbvenc;
72                 }
73                 clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
74                         clk_info->clk_name);
75                 if (IS_ERR(clk_info->vcodec_clk)) {
76                         mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
77                                 clk_info->clk_name);
78                         ret = PTR_ERR(clk_info->vcodec_clk);
79                         goto put_larbvenc;
80                 }
81         }
82
83         return 0;
84
85 put_larbvenc:
86         put_device(pm->larbvenc);
87         return ret;
88 }
89
90 void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
91 {
92         pm_runtime_disable(mtkdev->pm.dev);
93         put_device(mtkdev->pm.larbvenc);
94 }
95
96
97 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
98 {
99         struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
100         int ret, i = 0;
101
102         for (i = 0; i < enc_clk->clk_num; i++) {
103                 ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
104                 if (ret) {
105                         mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
106                                 enc_clk->clk_info[i].clk_name, ret);
107                         goto clkerr;
108                 }
109         }
110
111         ret = mtk_smi_larb_get(pm->larbvenc);
112         if (ret) {
113                 mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
114                 goto clkerr;
115         }
116         return;
117
118 clkerr:
119         for (i -= 1; i >= 0; i--)
120                 clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
121 }
122
123 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
124 {
125         struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
126         int i = 0;
127
128         mtk_smi_larb_put(pm->larbvenc);
129         for (i = enc_clk->clk_num - 1; i >= 0; i--)
130                 clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
131 }
This page took 0.053065 seconds and 4 git commands to generate.