lkml.org 
[lkml]   [2022]   [May]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/4] soc: mediatek: Add support of WAYEN operations
    Date
    From: Alexandre Bailon <abailon@baylibre.com>

    This updates the power domain to support WAYEN operations.
    This is required by the mt8365 for the MM power domain.

    Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
    Signed-off-by: Fabien Parent <fparent@baylibre.com>
    ---
    drivers/soc/mediatek/mtk-pm-domains.c | 64 +++++++++++++++++++++------
    drivers/soc/mediatek/mtk-pm-domains.h | 27 ++++++-----
    2 files changed, 67 insertions(+), 24 deletions(-)

    diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
    index 5ced254b082b..90b91b3b19a8 100644
    --- a/drivers/soc/mediatek/mtk-pm-domains.c
    +++ b/drivers/soc/mediatek/mtk-pm-domains.c
    @@ -44,6 +44,7 @@ struct scpsys_domain {
    struct clk_bulk_data *subsys_clks;
    struct regmap *infracfg;
    struct regmap *smi;
    + struct regmap *infracfg_nao;
    struct regulator *supply;
    };

    @@ -116,23 +117,38 @@ static int scpsys_sram_disable(struct scpsys_domain *pd)
    MTK_POLL_TIMEOUT);
    }

    -static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd, struct regmap *regmap)
    +static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd,
    + struct regmap *regmap, struct regmap *infracfg_nao)
    {
    int i, ret;

    for (i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
    - u32 val, mask = bpd[i].bus_prot_mask;
    + u32 mask = bpd[i].bus_prot_mask;
    + u32 val = mask, sta_mask = mask;
    + struct regmap *ack_regmap = regmap;

    if (!mask)
    break;

    + if (bpd[i].wayen) {
    + if (!infracfg_nao)
    + return -ENODEV;
    +
    + val = 0;
    + sta_mask = bpd[i].bus_prot_sta_mask;
    + ack_regmap = infracfg_nao;
    + }
    +
    if (bpd[i].bus_prot_reg_update)
    - regmap_set_bits(regmap, bpd[i].bus_prot_set, mask);
    + regmap_update_bits(regmap, bpd[i].bus_prot_set, mask, val);
    else
    regmap_write(regmap, bpd[i].bus_prot_set, mask);

    - ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
    - val, (val & mask) == mask,
    + if (bpd[i].ignore_clr_ack)
    + continue;
    +
    + ret = regmap_read_poll_timeout(ack_regmap, bpd[i].bus_prot_sta,
    + val, (val & sta_mask) == sta_mask,
    MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
    if (ret)
    return ret;
    @@ -145,34 +161,49 @@ static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
    {
    int ret;

    - ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg, pd->infracfg);
    + ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg,
    + pd->infracfg, pd->infracfg_nao);
    if (ret)
    return ret;

    - return _scpsys_bus_protect_enable(pd->data->bp_smi, pd->smi);
    + return _scpsys_bus_protect_enable(pd->data->bp_smi, pd->smi, NULL);
    }

    +#define mask_cond(wayen, val, mask) \
    + ((wayen && ((val & mask) == mask)) || (!wayen && !(val & mask)))
    +
    static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd,
    - struct regmap *regmap)
    + struct regmap *regmap, struct regmap *infracfg_nao)
    {
    int i, ret;

    for (i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
    - u32 val, mask = bpd[i].bus_prot_mask;
    + u32 val = 0, mask = bpd[i].bus_prot_mask;
    + u32 sta_mask = mask;
    + struct regmap *ack_regmap = regmap;

    if (!mask)
    continue;

    + if (bpd[i].wayen) {
    + if (!infracfg_nao)
    + return -ENODEV;
    +
    + val = mask;
    + sta_mask = bpd[i].bus_prot_sta_mask;
    + ack_regmap = infracfg_nao;
    + }
    +
    if (bpd[i].bus_prot_reg_update)
    - regmap_clear_bits(regmap, bpd[i].bus_prot_clr, mask);
    + regmap_update_bits(regmap, bpd[i].bus_prot_clr, mask, val);
    else
    regmap_write(regmap, bpd[i].bus_prot_clr, mask);

    if (bpd[i].ignore_clr_ack)
    continue;

    - ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
    - val, !(val & mask),
    + ret = regmap_read_poll_timeout(ack_regmap, bpd[i].bus_prot_sta,
    + val, mask_cond(bpd[i].wayen, val, sta_mask),
    MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
    if (ret)
    return ret;
    @@ -185,11 +216,12 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
    {
    int ret;

    - ret = _scpsys_bus_protect_disable(pd->data->bp_smi, pd->smi);
    + ret = _scpsys_bus_protect_disable(pd->data->bp_smi, pd->smi, NULL);
    if (ret)
    return ret;

    - return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg);
    + return _scpsys_bus_protect_disable(pd->data->bp_infracfg,
    + pd->infracfg, pd->infracfg_nao);
    }

    static int scpsys_regulator_enable(struct regulator *supply)
    @@ -363,6 +395,10 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
    return ERR_CAST(pd->smi);
    }

    + pd->infracfg_nao = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg_nao");
    + if (IS_ERR(pd->infracfg_nao))
    + return ERR_CAST(pd->infracfg_nao);
    +
    num_clks = of_clk_get_parent_count(node);
    if (num_clks > 0) {
    /* Calculate number of subsys_clks */
    diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
    index daa24e890dd4..a3955d960233 100644
    --- a/drivers/soc/mediatek/mtk-pm-domains.h
    +++ b/drivers/soc/mediatek/mtk-pm-domains.h
    @@ -39,23 +39,28 @@

    #define SPM_MAX_BUS_PROT_DATA 6

    -#define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \
    - .bus_prot_mask = (_mask), \
    - .bus_prot_set = _set, \
    - .bus_prot_clr = _clr, \
    - .bus_prot_sta = _sta, \
    - .bus_prot_reg_update = _update, \
    - .ignore_clr_ack = _ignore, \
    +#define _BUS_PROT(_mask, _sta_mask, _set, _clr, _sta, _update, _ignore, _wayen) { \
    + .bus_prot_mask = (_mask), \
    + .bus_prot_set = _set, \
    + .bus_prot_clr = _clr, \
    + .bus_prot_sta = _sta, \
    + .bus_prot_sta_mask = _sta_mask, \
    + .bus_prot_reg_update = _update, \
    + .ignore_clr_ack = _ignore, \
    + .wayen = _wayen, \
    }

    #define BUS_PROT_WR(_mask, _set, _clr, _sta) \
    - _BUS_PROT(_mask, _set, _clr, _sta, false, false)
    + _BUS_PROT(_mask, _mask, _set, _clr, _sta, false, false, false)

    #define BUS_PROT_WR_IGN(_mask, _set, _clr, _sta) \
    - _BUS_PROT(_mask, _set, _clr, _sta, false, true)
    + _BUS_PROT(_mask, _mask, _set, _clr, _sta, false, true, false)

    #define BUS_PROT_UPDATE(_mask, _set, _clr, _sta) \
    - _BUS_PROT(_mask, _set, _clr, _sta, true, false)
    + _BUS_PROT(_mask, _mask, _set, _clr, _sta, true, false, false)
    +
    +#define BUS_PROT_WAYEN(_en_mask, _sta_mask, _set, _sta) \
    + _BUS_PROT(_en_mask, _sta_mask, _set, _set, _sta, true, false, true)

    #define BUS_PROT_UPDATE_TOPAXI(_mask) \
    BUS_PROT_UPDATE(_mask, \
    @@ -68,8 +73,10 @@ struct scpsys_bus_prot_data {
    u32 bus_prot_set;
    u32 bus_prot_clr;
    u32 bus_prot_sta;
    + u32 bus_prot_sta_mask;
    bool bus_prot_reg_update;
    bool ignore_clr_ack;
    + bool wayen;
    };

    /**
    --
    2.36.1
    \
     
     \ /
      Last update: 2022-05-30 22:43    [W:6.935 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site