linux/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c
<<
>>
Prefs
   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
  12#include "mtk_vcodec_enc_pm.h"
  13#include "mtk_vcodec_util.h"
  14
  15int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
  16{
  17        struct platform_device *pdev;
  18        struct mtk_vcodec_pm *pm;
  19        struct mtk_vcodec_clk *enc_clk;
  20        struct mtk_vcodec_clk_info *clk_info;
  21        int ret, i;
  22
  23        pdev = mtkdev->plat_dev;
  24        pm = &mtkdev->pm;
  25        memset(pm, 0, sizeof(struct mtk_vcodec_pm));
  26        pm->dev = &pdev->dev;
  27        enc_clk = &pm->venc_clk;
  28
  29        enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
  30                "clock-names");
  31        if (enc_clk->clk_num > 0) {
  32                enc_clk->clk_info = devm_kcalloc(&pdev->dev,
  33                        enc_clk->clk_num, sizeof(*clk_info),
  34                        GFP_KERNEL);
  35                if (!enc_clk->clk_info)
  36                        return -ENOMEM;
  37        } else {
  38                mtk_v4l2_err("Failed to get venc clock count");
  39                return -EINVAL;
  40        }
  41
  42        for (i = 0; i < enc_clk->clk_num; i++) {
  43                clk_info = &enc_clk->clk_info[i];
  44                ret = of_property_read_string_index(pdev->dev.of_node,
  45                        "clock-names", i, &clk_info->clk_name);
  46                if (ret) {
  47                        mtk_v4l2_err("venc failed to get clk name %d", i);
  48                        return ret;
  49                }
  50                clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
  51                        clk_info->clk_name);
  52                if (IS_ERR(clk_info->vcodec_clk)) {
  53                        mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
  54                                clk_info->clk_name);
  55                        return PTR_ERR(clk_info->vcodec_clk);
  56                }
  57        }
  58
  59        return 0;
  60}
  61
  62void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
  63{
  64        struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
  65        int ret, i = 0;
  66
  67        for (i = 0; i < enc_clk->clk_num; i++) {
  68                ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
  69                if (ret) {
  70                        mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
  71                                enc_clk->clk_info[i].clk_name, ret);
  72                        goto clkerr;
  73                }
  74        }
  75
  76        return;
  77
  78clkerr:
  79        for (i -= 1; i >= 0; i--)
  80                clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
  81}
  82
  83void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
  84{
  85        struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
  86        int i = 0;
  87
  88        for (i = enc_clk->clk_num - 1; i >= 0; i--)
  89                clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
  90}
  91