Files
BPI-CM9-Linux/aml-comp/hardware/amlogic/video_encoder/tahoe_v4l/tahoe_common.c
T

179 lines
5.0 KiB
C

/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Description:
*/
#include <linux/reset.h>
#include <linux/pm_runtime.h>
#include "tahoe_common.h"
u32 clock_a;
s32 clock_gate_count = 0;
void tahoe_hw_reset(void)
{
#if 0
if (IS_ERR(s_tahoe_rsts.core_rst) ||
IS_ERR(s_tahoe_rsts.a_rst) ||
IS_ERR(s_tahoe_rsts.apb_rst) ||
IS_ERR(s_tahoe_rsts.sys_rst)) {
return;
}
reset_control_reset(s_tahoe_rsts.core_rst);
reset_control_reset(s_tahoe_rsts.a_rst);
reset_control_reset(s_tahoe_rsts.apb_rst);
reset_control_reset(s_tahoe_rsts.sys_rst);
#endif
}
void tahoe_clk_put(struct device *dev, struct tahoe_clks *clks)
{
if (!(clks->sys_tahoe == NULL || IS_ERR(clks->sys_tahoe)))
devm_clk_put(dev, clks->sys_tahoe);
if (!(clks->tahoe_clk == NULL || IS_ERR(clks->tahoe_clk)))
devm_clk_put(dev, clks->tahoe_clk);
}
int tahoe_clk_get(struct device *dev, struct tahoe_clks *clks)
{
int ret;
clks->sys_tahoe = devm_clk_get(dev, "sys_tahoe");
if (IS_ERR(clks->sys_tahoe)) {
enc_pr(LOG_ERROR, "cannot get sys_tahoe clock\n");
clks->sys_tahoe = NULL;
//ret = -ENOENT;
//goto err;
}
/*
* "clk_tahoe" is used by the A9.
* For the same clock function, C5 uses "clk_tahoe_enc".
*/
clks->tahoe_clk = devm_clk_get(dev, "clk_tahoe");
if (IS_ERR(clks->tahoe_clk)) {
ret = PTR_ERR(clks->tahoe_clk);
if (ret != -ENOENT)
return ret;
clks->tahoe_clk = devm_clk_get(dev, "clk_tahoe_enc");
if (IS_ERR(clks->tahoe_clk)) {
ret = PTR_ERR(clks->tahoe_clk);
enc_pr(LOG_ERROR, "cannot get tahoe clock: %d\n", ret);
return ret;
}
}
return 0;
}
int tahoe_rst_get(struct device *dev, struct tahoe_rsts *rsts)
{
//int ret = 0;
rsts->core_rst = devm_reset_control_get(dev, "tahoe_core_rst");
if (IS_ERR(rsts->core_rst)) {
enc_pr(LOG_ERROR, "cannot get core_rst\n");
rsts->core_rst = NULL;
//ret = -ENOENT;
//goto err;
}
rsts->a_rst = devm_reset_control_get(dev, "tahoe_a_rst");
if (IS_ERR(rsts->a_rst)) {
enc_pr(LOG_ERROR, "cannot get a_rst\n");
rsts->a_rst = NULL;
//ret = -ENOENT;
//goto err;
}
rsts->apb_rst = devm_reset_control_get(dev, "tahoe_apb_rst");
if (IS_ERR(rsts->apb_rst)) {
enc_pr(LOG_ERROR, "cannot get apb_rst\n");
rsts->apb_rst = NULL;
//ret = -ENOENT;
//goto err;
}
rsts->sys_rst = devm_reset_control_get(dev, "tahoe_sys_rst");
if (IS_ERR(rsts->sys_rst)) {
enc_pr(LOG_ERROR, "cannot get sys_rst\n");
rsts->sys_rst = NULL;
//ret = -ENOENT;
//goto err;
}
return 0;
//err:
//return ret;
}
void tahoe_clk_enable(struct tahoe_clks *clks,struct platform_device *tahoe_pdev)
{
if (clks->sys_tahoe != NULL) {
clk_prepare_enable(clks->sys_tahoe);
}
if (clock_a > 0) {
enc_pr(LOG_INFO, "tahoe: desired clock_a freq %u\n", clock_a);
clk_set_rate(clks->tahoe_clk, clock_a);
} else
clk_set_rate(clks->tahoe_clk, 666666666);
clk_prepare_enable(clks->tahoe_clk);
enc_pr(LOG_DEBUG, "tahoe: %ld\n", clk_get_rate(clks->tahoe_clk));
/* the power on*/
pm_runtime_get_sync(&tahoe_pdev->dev);
mdelay(5);
enc_pr(LOG_INFO, "tahoe power stauts after poweron: %d\n", pm_runtime_active(&tahoe_pdev->dev));
/* reset */
tahoe_hw_reset(); //__need_modify__
/* gate the clocks */
#ifdef TAHOE_SUPPORT_CLOCK_CONTROL
enc_pr(LOG_INFO, "tahoe_clk_enable, now gate off the clock\n");
clk_disable(clks->tahoe_clk);
#endif
}
void tahoe_clk_disable(struct tahoe_clks *clks, struct platform_device *tahoe_pdev)
{
#ifdef TAHOE_SUPPORT_CLOCK_CONTROL
if (clock_gate_count > 0)
#endif
{
enc_pr(LOG_INFO, "tahoe unclosed clock %d\n", clock_gate_count);
clk_disable(clks->tahoe_clk);
clock_gate_count = 0;
}
clk_unprepare(clks->tahoe_clk);
if (clks->sys_tahoe != NULL) {
clk_disable_unprepare(clks->sys_tahoe);
}
/* the power off */
pm_runtime_put_sync(&tahoe_pdev->dev);
mdelay(5);
enc_pr(LOG_INFO, "tahoe power stauts after poweroff: %d\n", pm_runtime_active(&tahoe_pdev->dev));
}