mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
soc: rockchip: power-domain: Add protection for some special pd during startup
Use DOMAIN_RKXX_PROTECT to keepon the pd during startup. Change-Id: I526b97ec273e056e703b6e187d0e6ffec44e730c Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <soc/rockchip/pm_domains.h>
|
||||
#include <dt-bindings/power/px30-power.h>
|
||||
@@ -41,6 +42,7 @@ struct rockchip_domain_info {
|
||||
bool active_wakeup;
|
||||
int pwr_w_mask;
|
||||
int req_w_mask;
|
||||
bool keepon_startup;
|
||||
};
|
||||
|
||||
struct rockchip_pmu_info {
|
||||
@@ -90,9 +92,11 @@ struct rockchip_pmu {
|
||||
struct generic_pm_domain *domains[];
|
||||
};
|
||||
|
||||
static struct rockchip_pmu *g_pmu;
|
||||
|
||||
#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
|
||||
|
||||
#define DOMAIN(pwr, status, req, idle, ack, wakeup) \
|
||||
#define DOMAIN(pwr, status, req, idle, ack, wakeup, keepon) \
|
||||
{ \
|
||||
.pwr_mask = (pwr >= 0) ? BIT(pwr) : 0, \
|
||||
.status_mask = (status >= 0) ? BIT(status) : 0, \
|
||||
@@ -100,9 +104,10 @@ struct rockchip_pmu {
|
||||
.idle_mask = (idle >= 0) ? BIT(idle) : 0, \
|
||||
.ack_mask = (ack >= 0) ? BIT(ack) : 0, \
|
||||
.active_wakeup = wakeup, \
|
||||
.keepon_startup = keepon, \
|
||||
}
|
||||
|
||||
#define DOMAIN_M(pwr, status, req, idle, ack, wakeup) \
|
||||
#define DOMAIN_M(pwr, status, req, idle, ack, wakeup, keepon) \
|
||||
{ \
|
||||
.pwr_w_mask = (pwr >= 0) ? BIT(pwr + 16) : 0, \
|
||||
.pwr_mask = (pwr >= 0) ? BIT(pwr) : 0, \
|
||||
@@ -112,6 +117,7 @@ struct rockchip_pmu {
|
||||
.idle_mask = (idle >= 0) ? BIT(idle) : 0, \
|
||||
.ack_mask = (ack >= 0) ? BIT(ack) : 0, \
|
||||
.active_wakeup = wakeup, \
|
||||
.keepon_startup = keepon, \
|
||||
}
|
||||
|
||||
#define DOMAIN_RK3036(req, ack, idle, wakeup) \
|
||||
@@ -124,19 +130,31 @@ struct rockchip_pmu {
|
||||
}
|
||||
|
||||
#define DOMAIN_PX30(pwr, status, req, wakeup) \
|
||||
DOMAIN_M(pwr, status, req, (req) + 16, req, wakeup)
|
||||
DOMAIN_M(pwr, status, req, (req) + 16, req, wakeup, false)
|
||||
|
||||
#define DOMAIN_PX30_PROTECT(pwr, status, req, wakeup) \
|
||||
DOMAIN_M(pwr, status, req, (req) + 16, req, wakeup, true)
|
||||
|
||||
#define DOMAIN_RK3288(pwr, status, req, wakeup) \
|
||||
DOMAIN(pwr, status, req, req, (req) + 16, wakeup)
|
||||
DOMAIN(pwr, status, req, req, (req) + 16, wakeup, false)
|
||||
|
||||
#define DOMAIN_RK3288_PROTECT(pwr, status, req, wakeup) \
|
||||
DOMAIN(pwr, status, req, req, (req) + 16, wakeup, true)
|
||||
|
||||
#define DOMAIN_RK3328(pwr, status, req, wakeup) \
|
||||
DOMAIN_M(pwr, pwr, req, (req) + 10, req, wakeup)
|
||||
DOMAIN_M(pwr, pwr, req, (req) + 10, req, wakeup, false)
|
||||
|
||||
#define DOMAIN_RK3368(pwr, status, req, wakeup) \
|
||||
DOMAIN(pwr, status, req, (req) + 16, req, wakeup)
|
||||
DOMAIN(pwr, status, req, (req) + 16, req, wakeup, false)
|
||||
|
||||
#define DOMAIN_RK3368_PROTECT(pwr, status, req, wakeup) \
|
||||
DOMAIN(pwr, status, req, (req) + 16, req, wakeup, true)
|
||||
|
||||
#define DOMAIN_RK3399(pwr, status, req, wakeup) \
|
||||
DOMAIN(pwr, status, req, req, req, wakeup)
|
||||
DOMAIN(pwr, status, req, req, req, wakeup, false)
|
||||
|
||||
#define DOMAIN_RK3399_PROTECT(pwr, status, req, wakeup) \
|
||||
DOMAIN(pwr, status, req, req, req, wakeup, true)
|
||||
|
||||
static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
@@ -634,6 +652,11 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
|
||||
pd->genpd.flags = GENPD_FLAG_PM_CLK;
|
||||
if (pd_info->active_wakeup)
|
||||
pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
if (pd_info->keepon_startup) {
|
||||
pd->genpd.flags &= (~GENPD_FLAG_PM_CLK);
|
||||
pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
|
||||
}
|
||||
|
||||
pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd));
|
||||
|
||||
pmu->genpd_data.domains[id] = &pd->genpd;
|
||||
@@ -764,6 +787,47 @@ err_out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static void rockchip_pd_keepon_do_release(struct generic_pm_domain *genpd,
|
||||
struct rockchip_pm_domain *pd)
|
||||
{
|
||||
struct pm_domain_data *pm_data;
|
||||
int enable_count;
|
||||
|
||||
pd->genpd.flags &= (~GENPD_FLAG_ALWAYS_ON);
|
||||
pd->genpd.flags |= GENPD_FLAG_PM_CLK;
|
||||
list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
|
||||
if (!atomic_read(&pm_data->dev->power.usage_count)) {
|
||||
enable_count = 0;
|
||||
if (!pm_runtime_enabled(pm_data->dev)) {
|
||||
pm_runtime_enable(pm_data->dev);
|
||||
enable_count = 1;
|
||||
}
|
||||
pm_runtime_get_sync(pm_data->dev);
|
||||
pm_runtime_put_sync(pm_data->dev);
|
||||
if (enable_count)
|
||||
pm_runtime_disable(pm_data->dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __init rockchip_pd_keepon_release(void)
|
||||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
struct rockchip_pm_domain *pd;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_pmu->genpd_data.num_domains; i++) {
|
||||
genpd = g_pmu->genpd_data.domains[i];
|
||||
if (genpd) {
|
||||
pd = to_rockchip_pd(genpd);
|
||||
if (pd->info->keepon_startup)
|
||||
rockchip_pd_keepon_do_release(genpd, pd);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
late_initcall_sync(rockchip_pd_keepon_release);
|
||||
|
||||
static void __iomem *pd_base;
|
||||
|
||||
void rockchip_dump_pmu(void)
|
||||
@@ -892,6 +956,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&pmu_panic_block);
|
||||
|
||||
g_pmu = pmu;
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
@@ -905,8 +970,8 @@ static const struct rockchip_domain_info px30_pm_domains[] = {
|
||||
[PX30_PD_GMAC] = DOMAIN_PX30(10, 10, 6, false),
|
||||
[PX30_PD_MMC_NAND] = DOMAIN_PX30(11, 11, 5, false),
|
||||
[PX30_PD_VPU] = DOMAIN_PX30(12, 12, 14, false),
|
||||
[PX30_PD_VO] = DOMAIN_PX30(13, 13, 7, false),
|
||||
[PX30_PD_VI] = DOMAIN_PX30(14, 14, 8, false),
|
||||
[PX30_PD_VO] = DOMAIN_PX30_PROTECT(13, 13, 7, false),
|
||||
[PX30_PD_VI] = DOMAIN_PX30_PROTECT(14, 14, 8, false),
|
||||
[PX30_PD_GPU] = DOMAIN_PX30(15, 15, 2, false),
|
||||
};
|
||||
|
||||
@@ -914,7 +979,7 @@ static const struct rockchip_domain_info rk1808_pm_domains[] = {
|
||||
[RK1808_VD_NPU] = DOMAIN_PX30(15, 15, 2, false),
|
||||
[RK1808_PD_PCIE] = DOMAIN_PX30(9, 9, 4, true),
|
||||
[RK1808_PD_VPU] = DOMAIN_PX30(13, 13, 7, false),
|
||||
[RK1808_PD_VIO] = DOMAIN_PX30(14, 14, 8, false),
|
||||
[RK1808_PD_VIO] = DOMAIN_PX30_PROTECT(14, 14, 8, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3036_pm_domains[] = {
|
||||
@@ -930,7 +995,7 @@ static const struct rockchip_domain_info rk3036_pm_domains[] = {
|
||||
static const struct rockchip_domain_info rk3128_pm_domains[] = {
|
||||
[RK3128_PD_CORE] = DOMAIN_RK3288(0, 0, 4, false),
|
||||
[RK3128_PD_MSCH] = DOMAIN_RK3288(-1, -1, 6, true),
|
||||
[RK3128_PD_VIO] = DOMAIN_RK3288(3, 3, 2, false),
|
||||
[RK3128_PD_VIO] = DOMAIN_RK3288_PROTECT(3, 3, 2, false),
|
||||
[RK3128_PD_VIDEO] = DOMAIN_RK3288(2, 2, 1, false),
|
||||
[RK3128_PD_GPU] = DOMAIN_RK3288(1, 1, 3, false),
|
||||
};
|
||||
@@ -950,7 +1015,7 @@ static const struct rockchip_domain_info rk3228_pm_domains[] = {
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3288_pm_domains[] = {
|
||||
[RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false),
|
||||
[RK3288_PD_VIO] = DOMAIN_RK3288_PROTECT(7, 7, 4, false),
|
||||
[RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false),
|
||||
[RK3288_PD_VIDEO] = DOMAIN_RK3288(8, 8, 3, false),
|
||||
[RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2, false),
|
||||
@@ -970,7 +1035,7 @@ static const struct rockchip_domain_info rk3328_pm_domains[] = {
|
||||
|
||||
static const struct rockchip_domain_info rk3366_pm_domains[] = {
|
||||
[RK3366_PD_PERI] = DOMAIN_RK3368(10, 10, 6, true),
|
||||
[RK3366_PD_VIO] = DOMAIN_RK3368(14, 14, 8, false),
|
||||
[RK3366_PD_VIO] = DOMAIN_RK3368_PROTECT(14, 14, 8, false),
|
||||
[RK3366_PD_VIDEO] = DOMAIN_RK3368(13, 13, 7, false),
|
||||
[RK3366_PD_RKVDEC] = DOMAIN_RK3368(11, 11, 7, false),
|
||||
[RK3366_PD_WIFIBT] = DOMAIN_RK3368(8, 8, 9, false),
|
||||
@@ -980,7 +1045,7 @@ static const struct rockchip_domain_info rk3366_pm_domains[] = {
|
||||
|
||||
static const struct rockchip_domain_info rk3368_pm_domains[] = {
|
||||
[RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6, true),
|
||||
[RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8, false),
|
||||
[RK3368_PD_VIO] = DOMAIN_RK3368_PROTECT(15, 14, 8, false),
|
||||
[RK3368_PD_VIDEO] = DOMAIN_RK3368(14, 13, 7, false),
|
||||
[RK3368_PD_GPU_0] = DOMAIN_RK3368(16, 15, 2, false),
|
||||
[RK3368_PD_GPU_1] = DOMAIN_RK3368(17, 16, 2, false),
|
||||
@@ -995,22 +1060,22 @@ static const struct rockchip_domain_info rk3399_pm_domains[] = {
|
||||
[RK3399_PD_PERILP] = DOMAIN_RK3399(11, 11, 1, true),
|
||||
[RK3399_PD_PERIHP] = DOMAIN_RK3399(12, 12, 2, true),
|
||||
[RK3399_PD_CENTER] = DOMAIN_RK3399(13, 13, 14, true),
|
||||
[RK3399_PD_VIO] = DOMAIN_RK3399(14, 14, 17, false),
|
||||
[RK3399_PD_VIO] = DOMAIN_RK3399_PROTECT(14, 14, 17, false),
|
||||
[RK3399_PD_GPU] = DOMAIN_RK3399(15, 15, 0, false),
|
||||
[RK3399_PD_VCODEC] = DOMAIN_RK3399(16, 16, 3, false),
|
||||
[RK3399_PD_VDU] = DOMAIN_RK3399(17, 17, 4, false),
|
||||
[RK3399_PD_RGA] = DOMAIN_RK3399(18, 18, 5, false),
|
||||
[RK3399_PD_IEP] = DOMAIN_RK3399(19, 19, 6, false),
|
||||
[RK3399_PD_VO] = DOMAIN_RK3399(20, 20, -1, false),
|
||||
[RK3399_PD_VOPB] = DOMAIN_RK3399(-1, -1, 7, false),
|
||||
[RK3399_PD_VOPL] = DOMAIN_RK3399(-1, -1, 8, false),
|
||||
[RK3399_PD_VO] = DOMAIN_RK3399_PROTECT(20, 20, -1, false),
|
||||
[RK3399_PD_VOPB] = DOMAIN_RK3399_PROTECT(-1, -1, 7, false),
|
||||
[RK3399_PD_VOPL] = DOMAIN_RK3399_PROTECT(-1, -1, 8, false),
|
||||
[RK3399_PD_ISP0] = DOMAIN_RK3399(22, 22, 9, false),
|
||||
[RK3399_PD_ISP1] = DOMAIN_RK3399(23, 23, 10, false),
|
||||
[RK3399_PD_HDCP] = DOMAIN_RK3399(24, 24, 11, false),
|
||||
[RK3399_PD_GMAC] = DOMAIN_RK3399(25, 25, 23, true),
|
||||
[RK3399_PD_EMMC] = DOMAIN_RK3399(26, 26, 24, true),
|
||||
[RK3399_PD_USB3] = DOMAIN_RK3399(27, 27, 12, true),
|
||||
[RK3399_PD_EDP] = DOMAIN_RK3399(28, 28, 22, false),
|
||||
[RK3399_PD_EDP] = DOMAIN_RK3399_PROTECT(28, 28, 22, false),
|
||||
[RK3399_PD_GIC] = DOMAIN_RK3399(29, 29, 27, true),
|
||||
[RK3399_PD_SD] = DOMAIN_RK3399(30, 30, 28, true),
|
||||
[RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29, true),
|
||||
|
||||
Reference in New Issue
Block a user