linux/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016 MediaTek Inc.
   3 * Author: Tiffany Lin <tiffany.lin@mediatek.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 */
  14
  15#include <linux/clk.h>
  16#include <linux/of_address.h>
  17#include <linux/of_platform.h>
  18#include <linux/pm_runtime.h>
  19#include <soc/mediatek/smi.h>
  20
  21#include "mtk_vcodec_dec_pm.h"
  22#include "mtk_vcodec_util.h"
  23#include "mtk_vpu.h"
  24
  25int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
  26{
  27        struct device_node *node;
  28        struct platform_device *pdev;
  29        struct mtk_vcodec_pm *pm;
  30        int ret = 0;
  31
  32        pdev = mtkdev->plat_dev;
  33        pm = &mtkdev->pm;
  34        pm->mtkdev = mtkdev;
  35        node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
  36        if (!node) {
  37                mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
  38                return -1;
  39        }
  40
  41        pdev = of_find_device_by_node(node);
  42        if (WARN_ON(!pdev)) {
  43                of_node_put(node);
  44                return -1;
  45        }
  46        pm->larbvdec = &pdev->dev;
  47        pdev = mtkdev->plat_dev;
  48        pm->dev = &pdev->dev;
  49
  50        pm->vcodecpll = devm_clk_get(&pdev->dev, "vcodecpll");
  51        if (IS_ERR(pm->vcodecpll)) {
  52                mtk_v4l2_err("devm_clk_get vcodecpll fail");
  53                ret = PTR_ERR(pm->vcodecpll);
  54        }
  55
  56        pm->univpll_d2 = devm_clk_get(&pdev->dev, "univpll_d2");
  57        if (IS_ERR(pm->univpll_d2)) {
  58                mtk_v4l2_err("devm_clk_get univpll_d2 fail");
  59                ret = PTR_ERR(pm->univpll_d2);
  60        }
  61
  62        pm->clk_cci400_sel = devm_clk_get(&pdev->dev, "clk_cci400_sel");
  63        if (IS_ERR(pm->clk_cci400_sel)) {
  64                mtk_v4l2_err("devm_clk_get clk_cci400_sel fail");
  65                ret = PTR_ERR(pm->clk_cci400_sel);
  66        }
  67
  68        pm->vdec_sel = devm_clk_get(&pdev->dev, "vdec_sel");
  69        if (IS_ERR(pm->vdec_sel)) {
  70                mtk_v4l2_err("devm_clk_get vdec_sel fail");
  71                ret = PTR_ERR(pm->vdec_sel);
  72        }
  73
  74        pm->vdecpll = devm_clk_get(&pdev->dev, "vdecpll");
  75        if (IS_ERR(pm->vdecpll)) {
  76                mtk_v4l2_err("devm_clk_get vdecpll fail");
  77                ret = PTR_ERR(pm->vdecpll);
  78        }
  79
  80        pm->vencpll = devm_clk_get(&pdev->dev, "vencpll");
  81        if (IS_ERR(pm->vencpll)) {
  82                mtk_v4l2_err("devm_clk_get vencpll fail");
  83                ret = PTR_ERR(pm->vencpll);
  84        }
  85
  86        pm->venc_lt_sel = devm_clk_get(&pdev->dev, "venc_lt_sel");
  87        if (IS_ERR(pm->venc_lt_sel)) {
  88                mtk_v4l2_err("devm_clk_get venc_lt_sel fail");
  89                ret = PTR_ERR(pm->venc_lt_sel);
  90        }
  91
  92        pm->vdec_bus_clk_src = devm_clk_get(&pdev->dev, "vdec_bus_clk_src");
  93        if (IS_ERR(pm->vdec_bus_clk_src)) {
  94                mtk_v4l2_err("devm_clk_get vdec_bus_clk_src");
  95                ret = PTR_ERR(pm->vdec_bus_clk_src);
  96        }
  97
  98        pm_runtime_enable(&pdev->dev);
  99
 100        return ret;
 101}
 102
 103void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
 104{
 105        pm_runtime_disable(dev->pm.dev);
 106}
 107
 108void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 109{
 110        int ret;
 111
 112        ret = pm_runtime_get_sync(pm->dev);
 113        if (ret)
 114                mtk_v4l2_err("pm_runtime_get_sync fail %d", ret);
 115}
 116
 117void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 118{
 119        int ret;
 120
 121        ret = pm_runtime_put_sync(pm->dev);
 122        if (ret)
 123                mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 124}
 125
 126void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 127{
 128        int ret;
 129
 130        ret = clk_set_rate(pm->vcodecpll, 1482 * 1000000);
 131        if (ret)
 132                mtk_v4l2_err("clk_set_rate vcodecpll fail %d", ret);
 133
 134        ret = clk_set_rate(pm->vencpll, 800 * 1000000);
 135        if (ret)
 136                mtk_v4l2_err("clk_set_rate vencpll fail %d", ret);
 137
 138        ret = clk_prepare_enable(pm->vcodecpll);
 139        if (ret)
 140                mtk_v4l2_err("clk_prepare_enable vcodecpll fail %d", ret);
 141
 142        ret = clk_prepare_enable(pm->vencpll);
 143        if (ret)
 144                mtk_v4l2_err("clk_prepare_enable vencpll fail %d", ret);
 145
 146        ret = clk_prepare_enable(pm->vdec_bus_clk_src);
 147        if (ret)
 148                mtk_v4l2_err("clk_prepare_enable vdec_bus_clk_src fail %d",
 149                                ret);
 150
 151        ret = clk_prepare_enable(pm->venc_lt_sel);
 152        if (ret)
 153                mtk_v4l2_err("clk_prepare_enable venc_lt_sel fail %d", ret);
 154
 155        ret = clk_set_parent(pm->venc_lt_sel, pm->vdec_bus_clk_src);
 156        if (ret)
 157                mtk_v4l2_err("clk_set_parent venc_lt_sel vdec_bus_clk_src fail %d",
 158                                ret);
 159
 160        ret = clk_prepare_enable(pm->univpll_d2);
 161        if (ret)
 162                mtk_v4l2_err("clk_prepare_enable univpll_d2 fail %d", ret);
 163
 164        ret = clk_prepare_enable(pm->clk_cci400_sel);
 165        if (ret)
 166                mtk_v4l2_err("clk_prepare_enable clk_cci400_sel fail %d", ret);
 167
 168        ret = clk_set_parent(pm->clk_cci400_sel, pm->univpll_d2);
 169        if (ret)
 170                mtk_v4l2_err("clk_set_parent clk_cci400_sel univpll_d2 fail %d",
 171                                ret);
 172
 173        ret = clk_prepare_enable(pm->vdecpll);
 174        if (ret)
 175                mtk_v4l2_err("clk_prepare_enable vdecpll fail %d", ret);
 176
 177        ret = clk_prepare_enable(pm->vdec_sel);
 178        if (ret)
 179                mtk_v4l2_err("clk_prepare_enable vdec_sel fail %d", ret);
 180
 181        ret = clk_set_parent(pm->vdec_sel, pm->vdecpll);
 182        if (ret)
 183                mtk_v4l2_err("clk_set_parent vdec_sel vdecpll fail %d", ret);
 184
 185        ret = mtk_smi_larb_get(pm->larbvdec);
 186        if (ret)
 187                mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret);
 188
 189}
 190
 191void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 192{
 193        mtk_smi_larb_put(pm->larbvdec);
 194        clk_disable_unprepare(pm->vdec_sel);
 195        clk_disable_unprepare(pm->vdecpll);
 196        clk_disable_unprepare(pm->univpll_d2);
 197        clk_disable_unprepare(pm->clk_cci400_sel);
 198        clk_disable_unprepare(pm->venc_lt_sel);
 199        clk_disable_unprepare(pm->vdec_bus_clk_src);
 200        clk_disable_unprepare(pm->vencpll);
 201        clk_disable_unprepare(pm->vcodecpll);
 202}
 203