From: Weiyi Lu <weiyi.lu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
To: Matthias Brugger
<matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>,
Fan Chen <fan.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org,
Weiyi Lu <weiyi.lu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Subject: [PATCH 6/9] soc: mediatek: extend bus protection API
Date: Tue, 22 Aug 2017 18:28:19 +0800 [thread overview]
Message-ID: <1503397702-7201-7-git-send-email-weiyi.lu@mediatek.com> (raw)
In-Reply-To: <1503397702-7201-1-git-send-email-weiyi.lu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
MT2712 add "set/clear" bus control register to each control register set
instead of providing only one "enable" control register, we could avoid
the read-modify-write racing by using extend API with such new design.
By improving the mtk-infracfg bus protection implementation to
support set/clear bus protection control method by IC configuration.
Signed-off-by: Weiyi Lu <weiyi.lu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
drivers/soc/mediatek/mtk-infracfg.c | 32 ++++++++++----
drivers/soc/mediatek/mtk-scpsys.c | 81 +++++++++++++++++++++++++++--------
include/linux/soc/mediatek/infracfg.h | 12 ++++--
3 files changed, 96 insertions(+), 29 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
index dba3055..f55ceaa 100644
--- a/drivers/soc/mediatek/mtk-infracfg.c
+++ b/drivers/soc/mediatek/mtk-infracfg.c
@@ -17,30 +17,35 @@
#include <linux/soc/mediatek/infracfg.h>
#include <asm/processor.h>
-#define INFRA_TOPAXI_PROTECTEN 0x0220
-#define INFRA_TOPAXI_PROTECTSTA1 0x0228
-
/**
* mtk_infracfg_set_bus_protection - enable bus protection
* @regmap: The infracfg regmap
* @mask: The mask containing the protection bits to be enabled.
+ * @reg_set: The register used to enable protection bits.
+ * @reg_en: The register used to enable protection bits when there doesn't
+ * exist reg_set.
+ * @reg_sta: The register used to check the protection bits are enabled.
*
* This function enables the bus protection bits for disabled power
* domains so that the system does not hang when some unit accesses the
* bus while in power down.
*/
-int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
+ u32 reg_set, u32 reg_en, u32 reg_sta)
{
unsigned long expired;
u32 val;
int ret;
- regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask);
+ if (reg_set)
+ regmap_write(infracfg, reg_set, mask);
+ else
+ regmap_update_bits(infracfg, reg_en, mask, mask);
expired = jiffies + HZ;
while (1) {
- ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
+ ret = regmap_read(infracfg, reg_sta, &val);
if (ret)
return ret;
@@ -59,23 +64,32 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
* mtk_infracfg_clear_bus_protection - disable bus protection
* @regmap: The infracfg regmap
* @mask: The mask containing the protection bits to be disabled.
+ * @reg_clr: The register used to disable protection bits.
+ * @reg_en: The register used to disable protection bits when there doesn't
+ * exist reg_clr.
+ * @reg_sta: The register used to check the protection bits are disabled.
*
* This function disables the bus protection bits previously enabled with
* mtk_infracfg_set_bus_protection.
*/
-int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
+
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
+ u32 reg_clr, u32 reg_en, u32 reg_sta)
{
unsigned long expired;
int ret;
- regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
+ if (reg_clr)
+ regmap_write(infracfg, reg_clr, mask);
+ else
+ regmap_update_bits(infracfg, reg_en, mask, 0);
expired = jiffies + HZ;
while (1) {
u32 val;
- ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
+ ret = regmap_read(infracfg, reg_sta, &val);
if (ret)
return ret;
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index e1ce8b1..2569390 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -127,13 +127,25 @@ struct scp_ctrl_reg {
int pwr_sta2nd_offs;
};
+struct bus_prot_reg {
+ u32 set_offs;
+ u32 clr_offs;
+ u32 en_offs;
+ u32 sta_offs;
+};
+
+struct soc_reg {
+ struct scp_ctrl_reg scp_ctrl;
+ struct bus_prot_reg bus_prot;
+};
+
struct scp {
struct scp_domain *domains;
struct genpd_onecell_data pd_data;
struct device *dev;
void __iomem *base;
struct regmap *infracfg;
- struct scp_ctrl_reg ctrl_reg;
+ struct soc_reg soc_reg;
};
struct scp_subdomain {
@@ -146,16 +158,16 @@ struct scp_soc_data {
int num_domains;
const struct scp_subdomain *subdomains;
int num_subdomains;
- const struct scp_ctrl_reg regs;
+ const struct soc_reg regs;
};
static int scpsys_domain_is_on(struct scp_domain *scpd)
{
struct scp *scp = scpd->scp;
- u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
+ u32 status = readl(scp->base + scp->soc_reg.scp_ctrl.pwr_sta_offs) &
scpd->data->sta_mask;
- u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
+ u32 status2 = readl(scp->base + scp->soc_reg.scp_ctrl.pwr_sta2nd_offs) &
scpd->data->sta_mask;
/*
@@ -254,7 +266,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
if (scpd->data->bus_prot_mask) {
ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
- scpd->data->bus_prot_mask);
+ scpd->data->bus_prot_mask,
+ scp->soc_reg.bus_prot.clr_offs,
+ scp->soc_reg.bus_prot.en_offs,
+ scp->soc_reg.bus_prot.sta_offs);
if (ret)
goto err_pwr_ack;
}
@@ -289,7 +304,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
if (scpd->data->bus_prot_mask) {
ret = mtk_infracfg_set_bus_protection(scp->infracfg,
- scpd->data->bus_prot_mask);
+ scpd->data->bus_prot_mask,
+ scp->soc_reg.bus_prot.set_offs,
+ scp->soc_reg.bus_prot.en_offs,
+ scp->soc_reg.bus_prot.sta_offs);
if (ret)
goto out;
}
@@ -382,7 +400,7 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
static struct scp *init_scp(struct platform_device *pdev,
const struct scp_domain_data *scp_domain_data, int num,
- const struct scp_ctrl_reg *scp_ctrl_reg)
+ const struct soc_reg *soc_reg)
{
struct genpd_onecell_data *pd_data;
struct resource *res;
@@ -394,8 +412,13 @@ static struct scp *init_scp(struct platform_device *pdev,
if (!scp)
return ERR_PTR(-ENOMEM);
- scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
- scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
+ scp->soc_reg.scp_ctrl.pwr_sta_offs = soc_reg->scp_ctrl.pwr_sta_offs;
+ scp->soc_reg.scp_ctrl.pwr_sta2nd_offs =
+ soc_reg->scp_ctrl.pwr_sta2nd_offs;
+ scp->soc_reg.bus_prot.set_offs = soc_reg->bus_prot.set_offs;
+ scp->soc_reg.bus_prot.clr_offs = soc_reg->bus_prot.clr_offs;
+ scp->soc_reg.bus_prot.en_offs = soc_reg->bus_prot.en_offs;
+ scp->soc_reg.bus_prot.sta_offs = soc_reg->bus_prot.sta_offs;
scp->dev = &pdev->dev;
@@ -814,8 +837,14 @@ static void mtk_register_power_domains(struct platform_device *pdev,
.domains = scp_domain_data_mt2701,
.num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
.regs = {
- .pwr_sta_offs = SPM_PWR_STATUS,
- .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+ .scp_ctrl = {
+ .pwr_sta_offs = SPM_PWR_STATUS,
+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+ },
+ .bus_prot = {
+ .en_offs = INFRA_TOPAXI_PROTECTEN,
+ .sta_offs = INFRA_TOPAXI_PROTECTSTA1
+ },
}
};
@@ -825,8 +854,14 @@ static void mtk_register_power_domains(struct platform_device *pdev,
.subdomains = scp_subdomain_mt6797,
.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
.regs = {
- .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
- .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
+ .scp_ctrl = {
+ .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
+ },
+ .bus_prot = {
+ .en_offs = INFRA_TOPAXI_PROTECTEN,
+ .sta_offs = INFRA_TOPAXI_PROTECTSTA1
+ },
}
};
@@ -834,8 +869,14 @@ static void mtk_register_power_domains(struct platform_device *pdev,
.domains = scp_domain_data_mt7622,
.num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
.regs = {
- .pwr_sta_offs = SPM_PWR_STATUS,
- .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+ .scp_ctrl = {
+ .pwr_sta_offs = SPM_PWR_STATUS,
+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+ },
+ .bus_prot = {
+ .en_offs = INFRA_TOPAXI_PROTECTEN,
+ .sta_offs = INFRA_TOPAXI_PROTECTSTA1
+ },
}
};
@@ -845,8 +886,14 @@ static void mtk_register_power_domains(struct platform_device *pdev,
.subdomains = scp_subdomain_mt8173,
.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
.regs = {
- .pwr_sta_offs = SPM_PWR_STATUS,
- .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+ .scp_ctrl = {
+ .pwr_sta_offs = SPM_PWR_STATUS,
+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+ },
+ .bus_prot = {
+ .en_offs = INFRA_TOPAXI_PROTECTEN,
+ .sta_offs = INFRA_TOPAXI_PROTECTSTA1
+ },
}
};
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index a0182ec..c704af5 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -1,6 +1,11 @@
#ifndef __SOC_MEDIATEK_INFRACFG_H
#define __SOC_MEDIATEK_INFRACFG_H
+#define INFRA_TOPAXI_PROTECTEN 0x0220
+#define INFRA_TOPAXI_PROTECTSTA1 0x0228
+#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
+#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
+
#define MT8173_TOP_AXI_PROT_EN_MCI_M2 BIT(0)
#define MT8173_TOP_AXI_PROT_EN_MM_M0 BIT(1)
#define MT8173_TOP_AXI_PROT_EN_MM_M1 BIT(2)
@@ -27,7 +32,8 @@
#define MT7622_TOP_AXI_PROT_EN_WB (BIT(2) | BIT(6) | \
BIT(7) | BIT(8))
-int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
-int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
-
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
+ u32 reg_set, u32 reg_en, u32 reg_sta);
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
+ u32 reg_clr, u32 reg_en, u32 reg_sta);
#endif /* __SOC_MEDIATEK_INFRACFG_H */
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2017-08-22 10:28 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-22 10:28 [PATCH v2 0/9] Mediatek MT2712 clock and scpsys support Weiyi Lu
2017-08-22 10:28 ` [PATCH 1/9] dt-bindings: ARM: Mediatek: Document bindings for MT2712 Weiyi Lu
2017-08-22 10:28 ` [PATCH 2/9] clk: mediatek: Add dt-bindings for MT2712 clocks Weiyi Lu
2017-08-22 10:28 ` [PATCH 3/9] clk: mediatek: Add MT2712 clock support Weiyi Lu
2017-08-22 10:28 ` [PATCH 5/9] dt-bindings: soc: add MT2712 power dt-bindings Weiyi Lu
2017-08-22 10:28 ` [PATCH 7/9] soc: mediatek: add dependent clock jpgdec/audio for scpsys Weiyi Lu
[not found] ` <1503397702-7201-1-git-send-email-weiyi.lu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2017-08-22 10:28 ` [PATCH 4/9] arm: dts: mt2712: Add clock controller device nodes Weiyi Lu
2017-08-22 10:28 ` Weiyi Lu [this message]
2017-10-10 15:45 ` [PATCH 6/9] soc: mediatek: extend bus protection API Matthias Brugger
2017-10-16 6:38 ` Weiyi Lu
2017-10-16 15:04 ` Matthias Brugger
2017-08-22 10:28 ` [PATCH 8/9] soc: mediatek: add MT2712 scpsys support Weiyi Lu
2017-08-22 10:28 ` [PATCH 9/9] arm: dts: Add power controller device node of MT2712 Weiyi Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1503397702-7201-7-git-send-email-weiyi.lu@mediatek.com \
--to=weiyi.lu-nus5lvnupcjwk0htik3j/w@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=fan.chen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org \
--cc=jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=srv_heupstream-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).