Commit 04bde674 authored by Yunfei Dong's avatar Yunfei Dong Committed by Mauro Carvalho Chehab

media: mtk-vcodec: Using common interface to manage vdec/venc clock

Vdec: Using standard CCF interface to set parent clock and
clock rate in dtsi and using common interface to open/close
video decoder clock.
Venc: Using standard CCF interface to set parent clock in dtsi
and using common interface to open/close video encoder clock.
Signed-off-by: default avatarYunfei Dong <yunfei.dong@mediatek.com>
Signed-off-by: default avatarQianqian Yan <qianqian.yan@mediatek.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent d8501cc8
...@@ -27,11 +27,14 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) ...@@ -27,11 +27,14 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
struct device_node *node; struct device_node *node;
struct platform_device *pdev; struct platform_device *pdev;
struct mtk_vcodec_pm *pm; struct mtk_vcodec_pm *pm;
int ret = 0; struct mtk_vcodec_clk *dec_clk;
struct mtk_vcodec_clk_info *clk_info;
int i = 0, ret = 0;
pdev = mtkdev->plat_dev; pdev = mtkdev->plat_dev;
pm = &mtkdev->pm; pm = &mtkdev->pm;
pm->mtkdev = mtkdev; pm->mtkdev = mtkdev;
dec_clk = &pm->vdec_clk;
node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0); node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
if (!node) { if (!node) {
mtk_v4l2_err("of_parse_phandle mediatek,larb fail!"); mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
...@@ -47,52 +50,34 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) ...@@ -47,52 +50,34 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
pdev = mtkdev->plat_dev; pdev = mtkdev->plat_dev;
pm->dev = &pdev->dev; pm->dev = &pdev->dev;
pm->vcodecpll = devm_clk_get(&pdev->dev, "vcodecpll"); dec_clk->clk_num =
if (IS_ERR(pm->vcodecpll)) { of_property_count_strings(pdev->dev.of_node, "clock-names");
mtk_v4l2_err("devm_clk_get vcodecpll fail"); if (dec_clk->clk_num > 0) {
ret = PTR_ERR(pm->vcodecpll); dec_clk->clk_info = devm_kcalloc(&pdev->dev,
dec_clk->clk_num, sizeof(*clk_info),
GFP_KERNEL);
if (!dec_clk->clk_info)
return -ENOMEM;
} else {
mtk_v4l2_err("Failed to get vdec clock count");
return -EINVAL;
} }
pm->univpll_d2 = devm_clk_get(&pdev->dev, "univpll_d2"); for (i = 0; i < dec_clk->clk_num; i++) {
if (IS_ERR(pm->univpll_d2)) { clk_info = &dec_clk->clk_info[i];
mtk_v4l2_err("devm_clk_get univpll_d2 fail"); ret = of_property_read_string_index(pdev->dev.of_node,
ret = PTR_ERR(pm->univpll_d2); "clock-names", i, &clk_info->clk_name);
} if (ret) {
mtk_v4l2_err("Failed to get clock name id = %d", i);
pm->clk_cci400_sel = devm_clk_get(&pdev->dev, "clk_cci400_sel"); return ret;
if (IS_ERR(pm->clk_cci400_sel)) {
mtk_v4l2_err("devm_clk_get clk_cci400_sel fail");
ret = PTR_ERR(pm->clk_cci400_sel);
}
pm->vdec_sel = devm_clk_get(&pdev->dev, "vdec_sel");
if (IS_ERR(pm->vdec_sel)) {
mtk_v4l2_err("devm_clk_get vdec_sel fail");
ret = PTR_ERR(pm->vdec_sel);
}
pm->vdecpll = devm_clk_get(&pdev->dev, "vdecpll");
if (IS_ERR(pm->vdecpll)) {
mtk_v4l2_err("devm_clk_get vdecpll fail");
ret = PTR_ERR(pm->vdecpll);
} }
clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
pm->vencpll = devm_clk_get(&pdev->dev, "vencpll"); clk_info->clk_name);
if (IS_ERR(pm->vencpll)) { if (IS_ERR(clk_info->vcodec_clk)) {
mtk_v4l2_err("devm_clk_get vencpll fail"); mtk_v4l2_err("devm_clk_get (%d)%s fail", i,
ret = PTR_ERR(pm->vencpll); clk_info->clk_name);
return PTR_ERR(clk_info->vcodec_clk);
} }
pm->venc_lt_sel = devm_clk_get(&pdev->dev, "venc_lt_sel");
if (IS_ERR(pm->venc_lt_sel)) {
mtk_v4l2_err("devm_clk_get venc_lt_sel fail");
ret = PTR_ERR(pm->venc_lt_sel);
}
pm->vdec_bus_clk_src = devm_clk_get(&pdev->dev, "vdec_bus_clk_src");
if (IS_ERR(pm->vdec_bus_clk_src)) {
mtk_v4l2_err("devm_clk_get vdec_bus_clk_src");
ret = PTR_ERR(pm->vdec_bus_clk_src);
} }
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
...@@ -125,78 +110,36 @@ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) ...@@ -125,78 +110,36 @@ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
{ {
int ret; struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
int ret, i = 0;
ret = clk_set_rate(pm->vcodecpll, 1482 * 1000000);
if (ret) for (i = 0; i < dec_clk->clk_num; i++) {
mtk_v4l2_err("clk_set_rate vcodecpll fail %d", ret); ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
if (ret) {
ret = clk_set_rate(pm->vencpll, 800 * 1000000); mtk_v4l2_err("clk_prepare_enable %d %s fail %d", i,
if (ret) dec_clk->clk_info[i].clk_name, ret);
mtk_v4l2_err("clk_set_rate vencpll fail %d", ret); goto error;
}
ret = clk_prepare_enable(pm->vcodecpll); }
if (ret)
mtk_v4l2_err("clk_prepare_enable vcodecpll fail %d", ret);
ret = clk_prepare_enable(pm->vencpll);
if (ret)
mtk_v4l2_err("clk_prepare_enable vencpll fail %d", ret);
ret = clk_prepare_enable(pm->vdec_bus_clk_src);
if (ret)
mtk_v4l2_err("clk_prepare_enable vdec_bus_clk_src fail %d",
ret);
ret = clk_prepare_enable(pm->venc_lt_sel);
if (ret)
mtk_v4l2_err("clk_prepare_enable venc_lt_sel fail %d", ret);
ret = clk_set_parent(pm->venc_lt_sel, pm->vdec_bus_clk_src);
if (ret)
mtk_v4l2_err("clk_set_parent venc_lt_sel vdec_bus_clk_src fail %d",
ret);
ret = clk_prepare_enable(pm->univpll_d2);
if (ret)
mtk_v4l2_err("clk_prepare_enable univpll_d2 fail %d", ret);
ret = clk_prepare_enable(pm->clk_cci400_sel);
if (ret)
mtk_v4l2_err("clk_prepare_enable clk_cci400_sel fail %d", ret);
ret = clk_set_parent(pm->clk_cci400_sel, pm->univpll_d2);
if (ret)
mtk_v4l2_err("clk_set_parent clk_cci400_sel univpll_d2 fail %d",
ret);
ret = clk_prepare_enable(pm->vdecpll);
if (ret)
mtk_v4l2_err("clk_prepare_enable vdecpll fail %d", ret);
ret = clk_prepare_enable(pm->vdec_sel);
if (ret)
mtk_v4l2_err("clk_prepare_enable vdec_sel fail %d", ret);
ret = clk_set_parent(pm->vdec_sel, pm->vdecpll);
if (ret)
mtk_v4l2_err("clk_set_parent vdec_sel vdecpll fail %d", ret);
ret = mtk_smi_larb_get(pm->larbvdec); ret = mtk_smi_larb_get(pm->larbvdec);
if (ret) if (ret) {
mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret); mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret);
goto error;
}
return;
error:
for (i -= 1; i >= 0; i--)
clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
} }
void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
{ {
struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
int i = 0;
mtk_smi_larb_put(pm->larbvdec); mtk_smi_larb_put(pm->larbvdec);
clk_disable_unprepare(pm->vdec_sel); for (i = dec_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(pm->vdecpll); clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
clk_disable_unprepare(pm->univpll_d2);
clk_disable_unprepare(pm->clk_cci400_sel);
clk_disable_unprepare(pm->venc_lt_sel);
clk_disable_unprepare(pm->vdec_bus_clk_src);
clk_disable_unprepare(pm->vencpll);
clk_disable_unprepare(pm->vcodecpll);
} }
...@@ -175,23 +175,30 @@ struct mtk_enc_params { ...@@ -175,23 +175,30 @@ struct mtk_enc_params {
unsigned int force_intra; unsigned int force_intra;
}; };
/**
* struct mtk_vcodec_clk_info - Structure used to store clock name
*/
struct mtk_vcodec_clk_info {
const char *clk_name;
struct clk *vcodec_clk;
};
/**
* struct mtk_vcodec_clk - Structure used to store vcodec clock information
*/
struct mtk_vcodec_clk {
struct mtk_vcodec_clk_info *clk_info;
int clk_num;
};
/** /**
* struct mtk_vcodec_pm - Power management data structure * struct mtk_vcodec_pm - Power management data structure
*/ */
struct mtk_vcodec_pm { struct mtk_vcodec_pm {
struct clk *vdec_bus_clk_src; struct mtk_vcodec_clk vdec_clk;
struct clk *vencpll;
struct clk *vcodecpll;
struct clk *univpll_d2;
struct clk *clk_cci400_sel;
struct clk *vdecpll;
struct clk *vdec_sel;
struct clk *vencpll_d2;
struct clk *venc_sel;
struct clk *univpll1_d2;
struct clk *venc_lt_sel;
struct device *larbvdec; struct device *larbvdec;
struct mtk_vcodec_clk venc_clk;
struct device *larbvenc; struct device *larbvenc;
struct device *larbvenclt; struct device *larbvenclt;
struct device *dev; struct device *dev;
......
...@@ -27,9 +27,11 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev) ...@@ -27,9 +27,11 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
{ {
struct device_node *node; struct device_node *node;
struct platform_device *pdev; struct platform_device *pdev;
struct device *dev;
struct mtk_vcodec_pm *pm; struct mtk_vcodec_pm *pm;
int ret = 0; struct mtk_vcodec_clk *enc_clk;
struct mtk_vcodec_clk_info *clk_info;
int ret = 0, i = 0;
struct device *dev;
pdev = mtkdev->plat_dev; pdev = mtkdev->plat_dev;
pm = &mtkdev->pm; pm = &mtkdev->pm;
...@@ -37,6 +39,7 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev) ...@@ -37,6 +39,7 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
pm->mtkdev = mtkdev; pm->mtkdev = mtkdev;
pm->dev = &pdev->dev; pm->dev = &pdev->dev;
dev = &pdev->dev; dev = &pdev->dev;
enc_clk = &pm->venc_clk;
node = of_parse_phandle(dev->of_node, "mediatek,larb", 0); node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
if (!node) { if (!node) {
...@@ -68,28 +71,34 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev) ...@@ -68,28 +71,34 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
pdev = mtkdev->plat_dev; pdev = mtkdev->plat_dev;
pm->dev = &pdev->dev; pm->dev = &pdev->dev;
pm->vencpll_d2 = devm_clk_get(&pdev->dev, "venc_sel_src"); enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
if (IS_ERR(pm->vencpll_d2)) { "clock-names");
mtk_v4l2_err("devm_clk_get vencpll_d2 fail"); if (enc_clk->clk_num > 0) {
ret = PTR_ERR(pm->vencpll_d2); enc_clk->clk_info = devm_kcalloc(&pdev->dev,
enc_clk->clk_num, sizeof(*clk_info),
GFP_KERNEL);
if (!enc_clk->clk_info)
return -ENOMEM;
} else {
mtk_v4l2_err("Failed to get venc clock count");
return -EINVAL;
} }
pm->venc_sel = devm_clk_get(&pdev->dev, "venc_sel"); for (i = 0; i < enc_clk->clk_num; i++) {
if (IS_ERR(pm->venc_sel)) { clk_info = &enc_clk->clk_info[i];
mtk_v4l2_err("devm_clk_get venc_sel fail"); ret = of_property_read_string_index(pdev->dev.of_node,
ret = PTR_ERR(pm->venc_sel); "clock-names", i, &clk_info->clk_name);
if (ret) {
mtk_v4l2_err("venc failed to get clk name %d", i);
return ret;
} }
clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
pm->univpll1_d2 = devm_clk_get(&pdev->dev, "venc_lt_sel_src"); clk_info->clk_name);
if (IS_ERR(pm->univpll1_d2)) { if (IS_ERR(clk_info->vcodec_clk)) {
mtk_v4l2_err("devm_clk_get univpll1_d2 fail"); mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
ret = PTR_ERR(pm->univpll1_d2); clk_info->clk_name);
return PTR_ERR(clk_info->vcodec_clk);
} }
pm->venc_lt_sel = devm_clk_get(&pdev->dev, "venc_lt_sel");
if (IS_ERR(pm->venc_lt_sel)) {
mtk_v4l2_err("devm_clk_get venc_lt_sel fail");
ret = PTR_ERR(pm->venc_lt_sel);
} }
return ret; return ret;
...@@ -102,38 +111,45 @@ void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev) ...@@ -102,38 +111,45 @@ void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm) void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
{ {
int ret; struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
int ret, i = 0;
ret = clk_prepare_enable(pm->venc_sel);
if (ret) for (i = 0; i < enc_clk->clk_num; i++) {
mtk_v4l2_err("clk_prepare_enable fail %d", ret); ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
if (ret) {
ret = clk_set_parent(pm->venc_sel, pm->vencpll_d2); mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
if (ret) enc_clk->clk_info[i].clk_name, ret);
mtk_v4l2_err("clk_set_parent fail %d", ret); goto clkerr;
}
ret = clk_prepare_enable(pm->venc_lt_sel); }
if (ret)
mtk_v4l2_err("clk_prepare_enable fail %d", ret);
ret = clk_set_parent(pm->venc_lt_sel, pm->univpll1_d2);
if (ret)
mtk_v4l2_err("clk_set_parent fail %d", ret);
ret = mtk_smi_larb_get(pm->larbvenc); ret = mtk_smi_larb_get(pm->larbvenc);
if (ret) if (ret) {
mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret); mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
goto larbvencerr;
}
ret = mtk_smi_larb_get(pm->larbvenclt); ret = mtk_smi_larb_get(pm->larbvenclt);
if (ret) if (ret) {
mtk_v4l2_err("mtk_smi_larb_get larb4 fail %d", ret); mtk_v4l2_err("mtk_smi_larb_get larb4 fail %d", ret);
goto larbvenclterr;
}
return;
larbvenclterr:
mtk_smi_larb_put(pm->larbvenc);
larbvencerr:
clkerr:
for (i -= 1; i >= 0; i--)
clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
} }
void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm) void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
{ {
struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
int i = 0;
mtk_smi_larb_put(pm->larbvenc); mtk_smi_larb_put(pm->larbvenc);
mtk_smi_larb_put(pm->larbvenclt); mtk_smi_larb_put(pm->larbvenclt);
clk_disable_unprepare(pm->venc_lt_sel); for (i = enc_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(pm->venc_sel); clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment