diff options
author | Jason-JH Lin <jason-jh.lin@mediatek.com> | 2025-06-24 18:39:03 +0800 |
---|---|---|
committer | AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> | 2025-06-25 15:59:00 +0200 |
commit | 331db44e70dacfb6bf1e17d92fae7b1c9517ca6c (patch) | |
tree | bca8c8dc8b87f90ef4ae00e0449072a3498672d0 | |
parent | 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 (diff) |
soc: mediatek: mtk-mutex: Fix confusing usage of MUTEX_MOD2
The usage of MUTEX_MOD1 and MUTEX_MOD2 for calculating mod settings
over 32 has been confusing. To improve consistency and clarity, these
defines need to fit into the same MUTEX_MOD define as possible.
However, MUTEX_MOD1 cannot be directly used for all SoCs because,
for example, the mod1 register (0x34) of MT2712 is not adjacent to
its mod0 register (0x2c). To address this, a `mutex_mod1_reg` field
is introduced in the mutex driver data structure. This allows all
SoCs to use a unified MUTEX_MOD to determine their register offsets.
With this change, the separate usage of MUTEX_MOD1 and MUTEX_MOD2 is
eliminated, simplifying the logic for obtaining offsets and mod IDs.
Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20250624103928.408194-1-jason-jh.lin@mediatek.com
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-rw-r--r-- | drivers/soc/mediatek/mtk-mutex.c | 109 |
1 files changed, 56 insertions, 53 deletions
diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index aaa965d4b050..38179e8cd98f 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -17,16 +17,35 @@ #define MT2701_MUTEX0_MOD0 0x2c #define MT2701_MUTEX0_SOF0 0x30 +#define MT2701_MUTEX0_MOD1 0x34 + #define MT8183_MUTEX0_MOD0 0x30 +#define MT8183_MUTEX0_MOD1 0x34 #define MT8183_MUTEX0_SOF0 0x2c #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) -#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) -#define DISP_REG_MUTEX_MOD1(mutex_mod_reg, n) ((mutex_mod_reg) + 0x20 * (n) + 0x4) +/* + * Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods + * are present, hence requiring multiple 32-bits registers. + * + * The mutex_table_mod fully represents that by defining the number of + * the mod sequentially, later used as a bit number, which can be more + * than 0..31. + * + * In order to retain compatibility with older SoCs, we perform R/W on + * the single 32 bits registers, but this requires us to translate the + * mutex ID bit accordingly. + */ +#define DISP_REG_MUTEX_MOD(mutex, id, n) ({ \ + const typeof(mutex) _mutex = (mutex); \ + u32 _offset = (id) < 32 ? \ + _mutex->data->mutex_mod_reg : \ + _mutex->data->mutex_mod1_reg; \ + _offset + 0x20 * (n); \ +}) #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) -#define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) #define INT_MUTEX BIT(1) @@ -334,6 +353,7 @@ struct mtk_mutex_data { const u8 *mutex_table_mod; const u16 *mutex_sof; const u16 mutex_mod_reg; + const u16 mutex_mod1_reg; const u16 mutex_sof_reg; const bool no_clk; }; @@ -714,6 +734,7 @@ static const struct mtk_mutex_data mt2701_mutex_driver_data = { .mutex_mod = mt2701_mutex_mod, .mutex_sof = mt2712_mutex_sof, .mutex_mod_reg = MT2701_MUTEX0_MOD0, + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, .mutex_sof_reg = MT2701_MUTEX0_SOF0, }; @@ -721,6 +742,7 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = { .mutex_mod = mt2712_mutex_mod, .mutex_sof = mt2712_mutex_sof, .mutex_mod_reg = MT2701_MUTEX0_MOD0, + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, .mutex_sof_reg = MT2701_MUTEX0_SOF0, }; @@ -728,6 +750,7 @@ static const struct mtk_mutex_data mt6795_mutex_driver_data = { .mutex_mod = mt8173_mutex_mod, .mutex_sof = mt6795_mutex_sof, .mutex_mod_reg = MT2701_MUTEX0_MOD0, + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, .mutex_sof_reg = MT2701_MUTEX0_SOF0, }; @@ -735,6 +758,7 @@ static const struct mtk_mutex_data mt8167_mutex_driver_data = { .mutex_mod = mt8167_mutex_mod, .mutex_sof = mt8167_mutex_sof, .mutex_mod_reg = MT2701_MUTEX0_MOD0, + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, .mutex_sof_reg = MT2701_MUTEX0_SOF0, .no_clk = true, }; @@ -743,6 +767,7 @@ static const struct mtk_mutex_data mt8173_mutex_driver_data = { .mutex_mod = mt8173_mutex_mod, .mutex_sof = mt2712_mutex_sof, .mutex_mod_reg = MT2701_MUTEX0_MOD0, + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, .mutex_sof_reg = MT2701_MUTEX0_SOF0, }; @@ -750,6 +775,7 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { .mutex_mod = mt8183_mutex_mod, .mutex_sof = mt8183_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, .mutex_table_mod = mt8183_mutex_table_mod, .no_clk = true, @@ -757,6 +783,7 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = { .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, .mutex_table_mod = mt8186_mdp_mutex_table_mod, }; @@ -765,6 +792,7 @@ static const struct mtk_mutex_data mt8186_mutex_driver_data = { .mutex_mod = mt8186_mutex_mod, .mutex_sof = mt8186_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, }; @@ -772,12 +800,14 @@ static const struct mtk_mutex_data mt8188_mutex_driver_data = { .mutex_mod = mt8188_mutex_mod, .mutex_sof = mt8188_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, }; static const struct mtk_mutex_data mt8188_vpp_mutex_driver_data = { .mutex_sof = mt8188_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, .mutex_table_mod = mt8188_mdp_mutex_table_mod, }; @@ -786,6 +816,7 @@ static const struct mtk_mutex_data mt8192_mutex_driver_data = { .mutex_mod = mt8192_mutex_mod, .mutex_sof = mt8183_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, }; @@ -793,12 +824,14 @@ static const struct mtk_mutex_data mt8195_mutex_driver_data = { .mutex_mod = mt8195_mutex_mod, .mutex_sof = mt8195_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, }; static const struct mtk_mutex_data mt8195_vpp_mutex_driver_data = { .mutex_sof = mt8195_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, .mutex_table_mod = mt8195_mutex_table_mod, }; @@ -807,6 +840,7 @@ static const struct mtk_mutex_data mt8365_mutex_driver_data = { .mutex_mod = mt8365_mutex_mod, .mutex_sof = mt8183_mutex_sof, .mutex_mod_reg = MT8183_MUTEX0_MOD0, + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, .mutex_sof_reg = MT8183_MUTEX0_SOF0, .no_clk = true, }; @@ -859,7 +893,7 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex, struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, mutex[mutex->id]); unsigned int reg; - unsigned int sof_id; + unsigned int sof_id, mod_id; unsigned int offset; WARN_ON(&mtx->mutex[mutex->id] != mutex); @@ -890,18 +924,11 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex, sof_id = MUTEX_SOF_DP_INTF1; break; default: - if (mtx->data->mutex_mod[id] < 32) { - offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, - mutex->id); - reg = readl_relaxed(mtx->regs + offset); - reg |= 1 << mtx->data->mutex_mod[id]; - writel_relaxed(reg, mtx->regs + offset); - } else { - offset = DISP_REG_MUTEX_MOD2(mutex->id); - reg = readl_relaxed(mtx->regs + offset); - reg |= 1 << (mtx->data->mutex_mod[id] - 32); - writel_relaxed(reg, mtx->regs + offset); - } + offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_mod[id], mutex->id); + mod_id = mtx->data->mutex_mod[id] % 32; + reg = readl_relaxed(mtx->regs + offset); + reg |= BIT(mod_id); + writel_relaxed(reg, mtx->regs + offset); return; } @@ -917,6 +944,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex, struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, mutex[mutex->id]); unsigned int reg; + unsigned int mod_id; unsigned int offset; WARN_ON(&mtx->mutex[mutex->id] != mutex); @@ -936,18 +964,11 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex, mutex->id)); break; default: - if (mtx->data->mutex_mod[id] < 32) { - offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, - mutex->id); - reg = readl_relaxed(mtx->regs + offset); - reg &= ~(1 << mtx->data->mutex_mod[id]); - writel_relaxed(reg, mtx->regs + offset); - } else { - offset = DISP_REG_MUTEX_MOD2(mutex->id); - reg = readl_relaxed(mtx->regs + offset); - reg &= ~(1 << (mtx->data->mutex_mod[id] - 32)); - writel_relaxed(reg, mtx->regs + offset); - } + offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_mod[id], mutex->id); + mod_id = mtx->data->mutex_mod[id] % 32; + reg = readl_relaxed(mtx->regs + offset); + reg &= ~BIT(mod_id); + writel_relaxed(reg, mtx->regs + offset); break; } } @@ -1023,7 +1044,7 @@ int mtk_mutex_write_mod(struct mtk_mutex *mutex, struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, mutex[mutex->id]); unsigned int reg; - u32 reg_offset, id_offset = 0; + u32 offset, mod_id; WARN_ON(&mtx->mutex[mutex->id] != mutex); @@ -1033,34 +1054,16 @@ int mtk_mutex_write_mod(struct mtk_mutex *mutex, return -EINVAL; } - /* - * Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods - * are present, hence requiring multiple 32-bits registers. - * - * The mutex_table_mod fully represents that by defining the number of - * the mod sequentially, later used as a bit number, which can be more - * than 0..31. - * - * In order to retain compatibility with older SoCs, we perform R/W on - * the single 32 bits registers, but this requires us to translate the - * mutex ID bit accordingly. - */ - if (mtx->data->mutex_table_mod[idx] < 32) { - reg_offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, - mutex->id); - } else { - reg_offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg, - mutex->id); - id_offset = 32; - } + offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_table_mod[idx], mutex->id); + mod_id = mtx->data->mutex_table_mod[idx] % 32; - reg = readl_relaxed(mtx->regs + reg_offset); + reg = readl_relaxed(mtx->regs + offset); if (clear) - reg &= ~BIT(mtx->data->mutex_table_mod[idx] - id_offset); + reg &= ~BIT(mod_id); else - reg |= BIT(mtx->data->mutex_table_mod[idx] - id_offset); + reg |= BIT(mod_id); - writel_relaxed(reg, mtx->regs + reg_offset); + writel_relaxed(reg, mtx->regs + offset); return 0; } |