root/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mtk_vcodec_init_enc_pm
  2. mtk_vcodec_release_enc_pm
  3. mtk_vcodec_enc_clock_on
  4. mtk_vcodec_enc_clock_off

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3 * Copyright (c) 2016 MediaTek Inc.
   4 * Author: Tiffany Lin <tiffany.lin@mediatek.com>
   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 #include "mtk_vpu.h"
  16 
  17 
  18 int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
  19 {
  20         struct device_node *node;
  21         struct platform_device *pdev;
  22         struct mtk_vcodec_pm *pm;
  23         struct mtk_vcodec_clk *enc_clk;
  24         struct mtk_vcodec_clk_info *clk_info;
  25         int ret = 0, i = 0;
  26         struct device *dev;
  27 
  28         pdev = mtkdev->plat_dev;
  29         pm = &mtkdev->pm;
  30         memset(pm, 0, sizeof(struct mtk_vcodec_pm));
  31         pm->mtkdev = mtkdev;
  32         pm->dev = &pdev->dev;
  33         dev = &pdev->dev;
  34         enc_clk = &pm->venc_clk;
  35 
  36         node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
  37         if (!node) {
  38                 mtk_v4l2_err("no mediatek,larb found");
  39                 return -ENODEV;
  40         }
  41         pdev = of_find_device_by_node(node);
  42         of_node_put(node);
  43         if (!pdev) {
  44                 mtk_v4l2_err("no mediatek,larb device found");
  45                 return -ENODEV;
  46         }
  47         pm->larbvenc = &pdev->dev;
  48 
  49         node = of_parse_phandle(dev->of_node, "mediatek,larb", 1);
  50         if (!node) {
  51                 mtk_v4l2_err("no mediatek,larb found");
  52                 return -ENODEV;
  53         }
  54 
  55         pdev = of_find_device_by_node(node);
  56         of_node_put(node);
  57         if (!pdev) {
  58                 mtk_v4l2_err("no mediatek,larb device found");
  59                 return -ENODEV;
  60         }
  61 
  62         pm->larbvenclt = &pdev->dev;
  63         pdev = mtkdev->plat_dev;
  64         pm->dev = &pdev->dev;
  65 
  66         enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
  67                 "clock-names");
  68         if (enc_clk->clk_num > 0) {
  69                 enc_clk->clk_info = devm_kcalloc(&pdev->dev,
  70                         enc_clk->clk_num, sizeof(*clk_info),
  71                         GFP_KERNEL);
  72                 if (!enc_clk->clk_info)
  73                         return -ENOMEM;
  74         } else {
  75                 mtk_v4l2_err("Failed to get venc clock count");
  76                 return -EINVAL;
  77         }
  78 
  79         for (i = 0; i < enc_clk->clk_num; i++) {
  80                 clk_info = &enc_clk->clk_info[i];
  81                 ret = of_property_read_string_index(pdev->dev.of_node,
  82                         "clock-names", i, &clk_info->clk_name);
  83                 if (ret) {
  84                         mtk_v4l2_err("venc failed to get clk name %d", i);
  85                         return ret;
  86                 }
  87                 clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
  88                         clk_info->clk_name);
  89                 if (IS_ERR(clk_info->vcodec_clk)) {
  90                         mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
  91                                 clk_info->clk_name);
  92                         return PTR_ERR(clk_info->vcodec_clk);
  93                 }
  94         }
  95 
  96         return ret;
  97 }
  98 
  99 void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
 100 {
 101 }
 102 
 103 
 104 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 105 {
 106         struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
 107         int ret, i = 0;
 108 
 109         for (i = 0; i < enc_clk->clk_num; i++) {
 110                 ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
 111                 if (ret) {
 112                         mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
 113                                 enc_clk->clk_info[i].clk_name, ret);
 114                         goto clkerr;
 115                 }
 116         }
 117 
 118         ret = mtk_smi_larb_get(pm->larbvenc);
 119         if (ret) {
 120                 mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
 121                 goto larbvencerr;
 122         }
 123         ret = mtk_smi_larb_get(pm->larbvenclt);
 124         if (ret) {
 125                 mtk_v4l2_err("mtk_smi_larb_get larb4 fail %d", ret);
 126                 goto larbvenclterr;
 127         }
 128         return;
 129 
 130 larbvenclterr:
 131         mtk_smi_larb_put(pm->larbvenc);
 132 larbvencerr:
 133 clkerr:
 134         for (i -= 1; i >= 0; i--)
 135                 clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 136 }
 137 
 138 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 139 {
 140         struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
 141         int i = 0;
 142 
 143         mtk_smi_larb_put(pm->larbvenc);
 144         mtk_smi_larb_put(pm->larbvenclt);
 145         for (i = enc_clk->clk_num - 1; i >= 0; i--)
 146                 clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 147 }

/* [<][>][^][v][top][bottom][index][help] */