-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
soc: zte: pm_domains: Prepare for supporting ARMv8 zx2967 family
The ARMv8 zx2967 family (296718, 296716 etc) uses different value for controlling the power domain on/off registers, Choose the value depending on the compatible. Multiple domains are prepared for the family, this patch prepares the common functions. Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
- Loading branch information
Baoyou Xie
authored and
Shawn Guo
committed
Jan 11, 2017
1 parent
eea1d99
commit 4c2c2e3
Showing
6 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# | ||
# ZTE SoC drivers | ||
# | ||
menuconfig SOC_ZTE | ||
bool "ZTE SoC driver support" | ||
|
||
if SOC_ZTE | ||
|
||
config ZX2967_PM_DOMAINS | ||
bool "ZX2967 PM domains" | ||
depends on PM_GENERIC_DOMAINS | ||
|
||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# | ||
# ZTE SOC drivers | ||
# | ||
obj-$(CONFIG_ZX2967_PM_DOMAINS) += zx2967_pm_domains.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* | ||
* Copyright (C) 2017 ZTE Ltd. | ||
* | ||
* Author: Baoyou Xie <baoyou.xie@linaro.org> | ||
* License terms: GNU General Public License (GPL) version 2 | ||
*/ | ||
|
||
#include <linux/delay.h> | ||
#include <linux/err.h> | ||
#include <linux/io.h> | ||
#include <linux/of.h> | ||
|
||
#include "zx2967_pm_domains.h" | ||
|
||
#define PCU_DM_CLKEN(zpd) ((zpd)->reg_offset[REG_CLKEN]) | ||
#define PCU_DM_ISOEN(zpd) ((zpd)->reg_offset[REG_ISOEN]) | ||
#define PCU_DM_RSTEN(zpd) ((zpd)->reg_offset[REG_RSTEN]) | ||
#define PCU_DM_PWREN(zpd) ((zpd)->reg_offset[REG_PWREN]) | ||
#define PCU_DM_ACK_SYNC(zpd) ((zpd)->reg_offset[REG_ACK_SYNC]) | ||
|
||
static void __iomem *pcubase; | ||
|
||
static int zx2967_power_on(struct generic_pm_domain *domain) | ||
{ | ||
struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain; | ||
unsigned long loop = 1000; | ||
u32 val; | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd)); | ||
if (zpd->polarity == PWREN) | ||
val |= BIT(zpd->bit); | ||
else | ||
val &= ~BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd)); | ||
|
||
do { | ||
udelay(1); | ||
val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd)) | ||
& BIT(zpd->bit); | ||
} while (--loop && !val); | ||
|
||
if (!loop) { | ||
pr_err("Error: %s %s fail\n", __func__, domain->name); | ||
return -EIO; | ||
} | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd)); | ||
val |= BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd)); | ||
udelay(5); | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd)); | ||
val &= ~BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd)); | ||
udelay(5); | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd)); | ||
val |= BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd)); | ||
udelay(5); | ||
|
||
pr_debug("poweron %s\n", domain->name); | ||
|
||
return 0; | ||
} | ||
|
||
static int zx2967_power_off(struct generic_pm_domain *domain) | ||
{ | ||
struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain; | ||
unsigned long loop = 1000; | ||
u32 val; | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd)); | ||
val &= ~BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd)); | ||
udelay(5); | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd)); | ||
val |= BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd)); | ||
udelay(5); | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd)); | ||
val &= ~BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd)); | ||
udelay(5); | ||
|
||
val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd)); | ||
if (zpd->polarity == PWREN) | ||
val &= ~BIT(zpd->bit); | ||
else | ||
val |= BIT(zpd->bit); | ||
writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd)); | ||
|
||
do { | ||
udelay(1); | ||
val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd)) | ||
& BIT(zpd->bit); | ||
} while (--loop && val); | ||
|
||
if (!loop) { | ||
pr_err("Error: %s %s fail\n", __func__, domain->name); | ||
return -EIO; | ||
} | ||
|
||
pr_debug("poweroff %s\n", domain->name); | ||
|
||
return 0; | ||
} | ||
|
||
int zx2967_pd_probe(struct platform_device *pdev, | ||
struct generic_pm_domain **zx_pm_domains, | ||
int domain_num) | ||
{ | ||
struct genpd_onecell_data *genpd_data; | ||
struct resource *res; | ||
int i; | ||
|
||
genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL); | ||
if (!genpd_data) | ||
return -ENOMEM; | ||
|
||
genpd_data->domains = zx_pm_domains; | ||
genpd_data->num_domains = domain_num; | ||
|
||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
pcubase = devm_ioremap_resource(&pdev->dev, res); | ||
if (IS_ERR(pcubase)) { | ||
dev_err(&pdev->dev, "ioremap fail.\n"); | ||
return PTR_ERR(pcubase); | ||
} | ||
|
||
for (i = 0; i < domain_num; ++i) { | ||
zx_pm_domains[i]->power_on = zx2967_power_on; | ||
zx_pm_domains[i]->power_off = zx2967_power_off; | ||
|
||
pm_genpd_init(zx_pm_domains[i], NULL, false); | ||
} | ||
|
||
of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data); | ||
dev_info(&pdev->dev, "powerdomain init ok\n"); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Header for ZTE's Power Domain Driver support | ||
* | ||
* Copyright (C) 2017 ZTE Ltd. | ||
* | ||
* Author: Baoyou Xie <baoyou.xie@linaro.org> | ||
* License terms: GNU General Public License (GPL) version 2 | ||
*/ | ||
|
||
#ifndef __ZTE_ZX2967_PM_DOMAIN_H | ||
#define __ZTE_ZX2967_PM_DOMAIN_H | ||
|
||
#include <linux/platform_device.h> | ||
#include <linux/pm_domain.h> | ||
|
||
enum { | ||
REG_CLKEN, | ||
REG_ISOEN, | ||
REG_RSTEN, | ||
REG_PWREN, | ||
REG_PWRDN, | ||
REG_ACK_SYNC, | ||
|
||
/* The size of the array - must be last */ | ||
REG_ARRAY_SIZE, | ||
}; | ||
|
||
enum zx2967_power_polarity { | ||
PWREN, | ||
PWRDN, | ||
}; | ||
|
||
struct zx2967_pm_domain { | ||
struct generic_pm_domain dm; | ||
const u16 bit; | ||
const enum zx2967_power_polarity polarity; | ||
const u16 *reg_offset; | ||
}; | ||
|
||
int zx2967_pd_probe(struct platform_device *pdev, | ||
struct generic_pm_domain **zx_pm_domains, | ||
int domain_num); | ||
|
||
#endif /* __ZTE_ZX2967_PM_DOMAIN_H */ |