mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
video: rockchip: rga3: disable memory when RGA power off to save power
Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: I6499783fff415dcf62b03f44d1736157ae04eedf
This commit is contained in:
@@ -319,10 +319,18 @@ struct rga_timer {
|
||||
u32 busy_time_record;
|
||||
};
|
||||
|
||||
struct rga_grf_info {
|
||||
uint32_t offset;
|
||||
uint32_t open_val;
|
||||
uint32_t close_val;
|
||||
struct regmap *grf;
|
||||
};
|
||||
|
||||
struct rga_scheduler_t {
|
||||
struct device *dev;
|
||||
void __iomem *rga_base;
|
||||
struct rga_iommu_info *iommu_info;
|
||||
struct rga_grf_info grf_info;
|
||||
|
||||
struct clk *clks[RGA_MAX_BUS_CLK];
|
||||
int num_clks;
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#define pr_fmt(fmt) "rga: " fmt
|
||||
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
|
||||
#include "rga2_reg_info.h"
|
||||
#include "rga3_reg_info.h"
|
||||
#include "rga_dma_buf.h"
|
||||
@@ -372,6 +375,62 @@ static void rga_cancel_timer(void)
|
||||
}
|
||||
|
||||
#ifndef RGA_DISABLE_PM
|
||||
static int rga_grf_open(struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
if (scheduler->grf_info.grf && scheduler->grf_info.open_val)
|
||||
regmap_write(scheduler->grf_info.grf,
|
||||
scheduler->grf_info.offset,
|
||||
scheduler->grf_info.open_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_grf_close(struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
if (scheduler->grf_info.grf && scheduler->grf_info.close_val)
|
||||
regmap_write(scheduler->grf_info.grf,
|
||||
scheduler->grf_info.offset,
|
||||
scheduler->grf_info.close_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_grf_init(struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
int ret;
|
||||
uint32_t grf_offset = 0;
|
||||
uint32_t grf_open_value = 0, grf_close_value = 0;
|
||||
struct device_node *np = scheduler->dev->of_node;
|
||||
struct regmap *grf;
|
||||
|
||||
grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
|
||||
if (IS_ERR_OR_NULL(grf))
|
||||
return -EINVAL;
|
||||
|
||||
ret = of_property_read_u32(np, "rockchip,grf-offset", &grf_offset);
|
||||
if (ret)
|
||||
return -ENODATA;
|
||||
|
||||
ret = of_property_read_u32_index(np, "rockchip,grf-values",
|
||||
0, &grf_open_value);
|
||||
if (ret)
|
||||
return -ENODATA;
|
||||
|
||||
ret = of_property_read_u32_index(np, "rockchip,grf-values",
|
||||
1, &grf_close_value);
|
||||
if (ret)
|
||||
return -ENODATA;
|
||||
|
||||
scheduler->grf_info.grf = grf;
|
||||
scheduler->grf_info.offset = grf_offset;
|
||||
scheduler->grf_info.open_val = grf_open_value;
|
||||
scheduler->grf_info.close_val = grf_close_value;
|
||||
|
||||
pr_info("%s grf init successfully.\n", dev_driver_string(scheduler->dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rga_power_enable(struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
@@ -392,8 +451,10 @@ int rga_power_enable(struct rga_scheduler_t *scheduler)
|
||||
spin_lock_irqsave(&scheduler->irq_lock, flags);
|
||||
|
||||
scheduler->pd_refcount++;
|
||||
if (scheduler->status == RGA_SCHEDULER_IDLE)
|
||||
if (scheduler->status == RGA_SCHEDULER_IDLE) {
|
||||
scheduler->status = RGA_SCHEDULER_WORKING;
|
||||
rga_grf_open(scheduler);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
|
||||
|
||||
@@ -425,8 +486,10 @@ int rga_power_disable(struct rga_scheduler_t *scheduler)
|
||||
}
|
||||
|
||||
scheduler->pd_refcount--;
|
||||
if (scheduler->pd_refcount == 0)
|
||||
if (scheduler->pd_refcount == 0) {
|
||||
scheduler->status = RGA_SCHEDULER_IDLE;
|
||||
rga_grf_close(scheduler);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
|
||||
|
||||
@@ -1362,8 +1425,9 @@ static int rga_drv_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RGA_DISABLE_PM
|
||||
rga_grf_init(scheduler);
|
||||
|
||||
/* clk init */
|
||||
for (i = 0; i < match_data->num_clks; i++) {
|
||||
struct clk *clk = devm_clk_get(dev, match_data->clks[i]);
|
||||
@@ -1394,6 +1458,8 @@ static int rga_drv_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rga_grf_open(scheduler);
|
||||
#endif /* #ifndef RGA_DISABLE_PM */
|
||||
|
||||
scheduler->ops->get_version(scheduler);
|
||||
@@ -1419,6 +1485,8 @@ static int rga_drv_probe(struct platform_device *pdev)
|
||||
data->num_of_scheduler++;
|
||||
|
||||
#ifndef RGA_DISABLE_PM
|
||||
rga_grf_close(scheduler);
|
||||
|
||||
for (i = scheduler->num_clks - 1; i >= 0; i--)
|
||||
if (!IS_ERR(scheduler->clks[i]))
|
||||
clk_disable_unprepare(scheduler->clks[i]);
|
||||
|
||||
Reference in New Issue
Block a user