mtk_vcodec_enc_pm.c (2203B)
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}