diff options
Diffstat (limited to 'drivers/soc/mediatek/mtk-mutex.c')
-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; } |