refactor code of mtk-scpsys
-----BEGIN PGP SIGNATURE----- iQJLBAABCAA1FiEEiUuSfQSYnG8EMsBltDliWyzx00MFAl3JS8kXHG1hdHRoaWFz LmJnZ0BnbWFpbC5jb20ACgkQtDliWyzx00PvgxAAgIYOPkmQhwvpxhPYVDy5qlEE z5kGbUP4s1Rig9UBFP6OPE14nuy7g+hFM1PTgCHlVGv3/AIkHlQS5EU3WtYgu2Fi 7fM8GfAY66G+FFoLq08T3TDudGnp9HyOS/tHF0wGtyjp7aeNx096FgFHfIBCeDsk 8sARrKuFahrau/X3ev9nKctFRGu1VzCDKweqCmk9U7SPsGUUMziSdN3p9j7FPbeI DKxSLzp/TqFtgiAbGYUlMieQWAvP4XKvo6sxXXn/vlG/PRUpuZY2Nv3D0ZeU7kGv rbOe5Frt/2CL/EOrUJ5kPjwdkt1QUDEkZQHC2qIA7wDoKuPYoTkDzAeaFBvE7Eav DXCreOUzz3w8QgvNWNV/HMQa6b9O4uozPex9Ve4ugTnwDUR9UmGh7IbCnh8M0y4Z s+C/ducbV92hW4ZVpRJMDFm7SgPl5Dg9Bb7KkEEvwQh4tp49rq8bobNyJTI+uUVi +seMLI9EtWM4fT2VWSpOepyfDNYYAYXSpWpjznePCBAvdyN2SUYQdwI+sCqQOonX g1mg+oWVEUBXbAW70ztBkmPHywPV4pX18yEBDZYQNuOBvChzclGCbiOsUbv3FtX2 LQuEcYK0BA4NVtXuOb1Nfc7ge7Om/OSFJC4II+CzuO74gMqHrT8Vbu758WooMWVZ UigZJy1oBbzYyzcaAbY= =Zp8l -----END PGP SIGNATURE----- Merge tag 'v5.4-next-soc' of https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into arm/drivers refactor code of mtk-scpsys * tag 'v5.4-next-soc' of https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux: soc: mediatek: Refactor bus protection control soc: mediatek: Refactor sram control soc: mediatek: Refactor clock control soc: mediatek: Refactor regulator control soc: mediatek: Refactor polling timeout and documentation Link: https://lore.kernel.org/r/294422a4-37b2-def5-5d32-8988f27c3a5b@gmail.com Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
01d1a860a5
|
@ -21,7 +21,7 @@
|
|||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
#define MTK_POLL_DELAY_US 10
|
||||
#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
|
||||
#define MTK_POLL_TIMEOUT USEC_PER_SEC
|
||||
|
||||
#define MTK_SCPD_ACTIVE_WAKEUP BIT(0)
|
||||
#define MTK_SCPD_FWAIT_SRAM BIT(1)
|
||||
|
@ -108,6 +108,17 @@ static const char * const clk_names[] = {
|
|||
|
||||
#define MAX_CLKS 3
|
||||
|
||||
/**
|
||||
* struct scp_domain_data - scp domain data for power on/off flow
|
||||
* @name: The domain name.
|
||||
* @sta_mask: The mask for power on/off status bit.
|
||||
* @ctl_offs: The offset for main power control register.
|
||||
* @sram_pdn_bits: The mask for sram power control bits.
|
||||
* @sram_pdn_ack_bits: The mask for sram power control acked bits.
|
||||
* @bus_prot_mask: The mask for single step bus protection.
|
||||
* @clk_id: The basic clocks required by this power domain.
|
||||
* @caps: The flag for active wake-up action.
|
||||
*/
|
||||
struct scp_domain_data {
|
||||
const char *name;
|
||||
u32 sta_mask;
|
||||
|
@ -180,32 +191,132 @@ static int scpsys_domain_is_on(struct scp_domain *scpd)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int scpsys_regulator_enable(struct scp_domain *scpd)
|
||||
{
|
||||
if (!scpd->supply)
|
||||
return 0;
|
||||
|
||||
return regulator_enable(scpd->supply);
|
||||
}
|
||||
|
||||
static int scpsys_regulator_disable(struct scp_domain *scpd)
|
||||
{
|
||||
if (!scpd->supply)
|
||||
return 0;
|
||||
|
||||
return regulator_disable(scpd->supply);
|
||||
}
|
||||
|
||||
static void scpsys_clk_disable(struct clk *clk[], int max_num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = max_num - 1; i >= 0; i--)
|
||||
clk_disable_unprepare(clk[i]);
|
||||
}
|
||||
|
||||
static int scpsys_clk_enable(struct clk *clk[], int max_num)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < max_num && clk[i]; i++) {
|
||||
ret = clk_prepare_enable(clk[i]);
|
||||
if (ret) {
|
||||
scpsys_clk_disable(clk, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
|
||||
{
|
||||
u32 val;
|
||||
u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
|
||||
int tmp;
|
||||
|
||||
val = readl(ctl_addr);
|
||||
val &= ~scpd->data->sram_pdn_bits;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
/* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
|
||||
if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
|
||||
/*
|
||||
* Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
|
||||
* MT7622_POWER_DOMAIN_WB and thus just a trivial setup
|
||||
* is applied here.
|
||||
*/
|
||||
usleep_range(12000, 12100);
|
||||
} else {
|
||||
/* Either wait until SRAM_PDN_ACK all 1 or 0 */
|
||||
int ret = readl_poll_timeout(ctl_addr, tmp,
|
||||
(tmp & pdn_ack) == 0,
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
|
||||
{
|
||||
u32 val;
|
||||
u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
|
||||
int tmp;
|
||||
|
||||
val = readl(ctl_addr);
|
||||
val |= scpd->data->sram_pdn_bits;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
/* Either wait until SRAM_PDN_ACK all 1 or 0 */
|
||||
return readl_poll_timeout(ctl_addr, tmp,
|
||||
(tmp & pdn_ack) == pdn_ack,
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
}
|
||||
|
||||
static int scpsys_bus_protect_enable(struct scp_domain *scpd)
|
||||
{
|
||||
struct scp *scp = scpd->scp;
|
||||
|
||||
if (!scpd->data->bus_prot_mask)
|
||||
return 0;
|
||||
|
||||
return mtk_infracfg_set_bus_protection(scp->infracfg,
|
||||
scpd->data->bus_prot_mask,
|
||||
scp->bus_prot_reg_update);
|
||||
}
|
||||
|
||||
static int scpsys_bus_protect_disable(struct scp_domain *scpd)
|
||||
{
|
||||
struct scp *scp = scpd->scp;
|
||||
|
||||
if (!scpd->data->bus_prot_mask)
|
||||
return 0;
|
||||
|
||||
return mtk_infracfg_clear_bus_protection(scp->infracfg,
|
||||
scpd->data->bus_prot_mask,
|
||||
scp->bus_prot_reg_update);
|
||||
}
|
||||
|
||||
static int scpsys_power_on(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
|
||||
struct scp *scp = scpd->scp;
|
||||
void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
|
||||
u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
|
||||
u32 val;
|
||||
int ret, tmp;
|
||||
int i;
|
||||
|
||||
if (scpd->supply) {
|
||||
ret = regulator_enable(scpd->supply);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
ret = scpsys_regulator_enable(scpd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
|
||||
ret = clk_prepare_enable(scpd->clk[i]);
|
||||
if (ret) {
|
||||
for (--i; i >= 0; i--)
|
||||
clk_disable_unprepare(scpd->clk[i]);
|
||||
|
||||
goto err_clk;
|
||||
}
|
||||
}
|
||||
ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
|
||||
/* subsys power on */
|
||||
val = readl(ctl_addr);
|
||||
val |= PWR_ON_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
@ -227,43 +338,20 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
val |= PWR_RST_B_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val &= ~scpd->data->sram_pdn_bits;
|
||||
writel(val, ctl_addr);
|
||||
ret = scpsys_sram_enable(scpd, ctl_addr);
|
||||
if (ret < 0)
|
||||
goto err_pwr_ack;
|
||||
|
||||
/* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
|
||||
if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
|
||||
/*
|
||||
* Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
|
||||
* MT7622_POWER_DOMAIN_WB and thus just a trivial setup is
|
||||
* applied here.
|
||||
*/
|
||||
usleep_range(12000, 12100);
|
||||
|
||||
} else {
|
||||
ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
goto err_pwr_ack;
|
||||
}
|
||||
|
||||
if (scpd->data->bus_prot_mask) {
|
||||
ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
|
||||
scpd->data->bus_prot_mask,
|
||||
scp->bus_prot_reg_update);
|
||||
if (ret)
|
||||
goto err_pwr_ack;
|
||||
}
|
||||
ret = scpsys_bus_protect_disable(scpd);
|
||||
if (ret < 0)
|
||||
goto err_pwr_ack;
|
||||
|
||||
return 0;
|
||||
|
||||
err_pwr_ack:
|
||||
for (i = MAX_CLKS - 1; i >= 0; i--) {
|
||||
if (scpd->clk[i])
|
||||
clk_disable_unprepare(scpd->clk[i]);
|
||||
}
|
||||
scpsys_clk_disable(scpd->clk, MAX_CLKS);
|
||||
err_clk:
|
||||
if (scpd->supply)
|
||||
regulator_disable(scpd->supply);
|
||||
scpsys_regulator_disable(scpd);
|
||||
|
||||
dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
|
||||
|
||||
|
@ -275,29 +363,19 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
|
|||
struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
|
||||
struct scp *scp = scpd->scp;
|
||||
void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
|
||||
u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
|
||||
u32 val;
|
||||
int ret, tmp;
|
||||
int i;
|
||||
|
||||
if (scpd->data->bus_prot_mask) {
|
||||
ret = mtk_infracfg_set_bus_protection(scp->infracfg,
|
||||
scpd->data->bus_prot_mask,
|
||||
scp->bus_prot_reg_update);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
val = readl(ctl_addr);
|
||||
val |= scpd->data->sram_pdn_bits;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
/* wait until SRAM_PDN_ACK all 1 */
|
||||
ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
ret = scpsys_bus_protect_enable(scpd);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = scpsys_sram_disable(scpd, ctl_addr);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* subsys power off */
|
||||
val = readl(ctl_addr);
|
||||
val |= PWR_ISO_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
|
@ -319,11 +397,11 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
|
|||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
|
||||
clk_disable_unprepare(scpd->clk[i]);
|
||||
scpsys_clk_disable(scpd->clk, MAX_CLKS);
|
||||
|
||||
if (scpd->supply)
|
||||
regulator_disable(scpd->supply);
|
||||
ret = scpsys_regulator_disable(scpd);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue