Message ID | 20220301100246.2153-5-moudy.ho@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add mmsys and mutex support for MDP | expand |
Hi, Moudy: On Tue, 2022-03-01 at 18:02 +0800, Moudy Ho wrote: > Considering that some functions have timing requirements > in specific situation, this patch adds several interface that > operate registers by CMDQ. > > Signed-off-by: Moudy Ho <moudy.ho@mediatek.com> > Reviewed-by: AngeloGioacchino Del Regno < > angelogioacchino.delregno@collabora.com> > --- > drivers/soc/mediatek/mtk-mutex.c | 72 > +++++++++++++++++++++++++- > include/linux/soc/mediatek/mtk-mutex.h | 6 +++ > 2 files changed, 76 insertions(+), 2 deletions(-) > > diff --git a/drivers/soc/mediatek/mtk-mutex.c > b/drivers/soc/mediatek/mtk-mutex.c > index a6268ecde240..a45864183cd1 100644 > --- a/drivers/soc/mediatek/mtk-mutex.c > +++ b/drivers/soc/mediatek/mtk-mutex.c > @@ -7,10 +7,14 @@ > #include <linux/iopoll.h> > #include <linux/module.h> > #include <linux/of_device.h> > +#include <linux/of_address.h> > #include <linux/platform_device.h> > #include <linux/regmap.h> > #include <linux/soc/mediatek/mtk-mmsys.h> > #include <linux/soc/mediatek/mtk-mutex.h> > +#include <linux/soc/mediatek/mtk-cmdq.h> > + > +#define MTK_MUTEX_ENABLE BIT(0) > > #define MT2701_MUTEX0_MOD0 0x2c > #define MT2701_MUTEX0_SOF0 0x30 > @@ -173,6 +177,7 @@ struct mtk_mutex_data { > const unsigned int mutex_mdp_mod_mask; > const unsigned int mutex_mdp_sof_mask; > const bool no_clk; > + const bool has_gce_client_reg; > }; > > struct mtk_mutex_ctx { > @@ -181,6 +186,8 @@ struct mtk_mutex_ctx { > void __iomem *regs; > struct mtk_mutex mutex[10]; > const struct mtk_mutex_data *data; > + phys_addr_t addr; > + struct cmdq_client_reg cmdq_reg; > }; > > static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { > @@ -374,6 +381,7 @@ static const struct mtk_mutex_data > mt8183_mutex_driver_data = { > .mutex_mdp_mod_mask = MT8183_MUTEX_MDP_MOD_MASK, > .mutex_mdp_sof_mask = MT8183_MUTEX_MDP_SOF_MASK, > .no_clk = true, > + .has_gce_client_reg = true, > }; > > static const struct mtk_mutex_data mt8186_mutex_driver_data = { > @@ -553,6 +561,25 @@ u32 mtk_mutex_get_mdp_mod(struct mtk_mutex > *mutex, enum mtk_mdp_comp_id id) > } > EXPORT_SYMBOL_GPL(mtk_mutex_get_mdp_mod); > > +void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod, > + struct mmsys_cmdq_cmd *cmd) > +{ > + struct mtk_mutex_ctx *mtx = container_of(mutex, struct > mtk_mutex_ctx, > + mutex[mutex->id]); > + unsigned int offset; > + > + WARN_ON(&mtx->mutex[mutex->id] != mutex); > + > + offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, mutex- > >id); > + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + > offset, > + mod, mtx->data->mutex_mdp_mod_mask); > + > + offset = DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex- > >id); > + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + > offset, > + 0, mtx->data->mutex_mdp_sof_mask); > +} > +EXPORT_SYMBOL_GPL(mtk_mutex_add_mod_by_cmdq); > + > void mtk_mutex_enable(struct mtk_mutex *mutex) > { > struct mtk_mutex_ctx *mtx = container_of(mutex, struct > mtk_mutex_ctx, > @@ -564,6 +591,20 @@ void mtk_mutex_enable(struct mtk_mutex *mutex) > } > EXPORT_SYMBOL_GPL(mtk_mutex_enable); > > +void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, > + struct mmsys_cmdq_cmd *cmd) There are 10 mutex and you could bind each pipeline to one mutex and always enable it. I think it's not necessary to frequently enable/disable mutex. > +{ > + struct mtk_mutex_ctx *mtx = container_of(mutex, struct > mtk_mutex_ctx, > + mutex[mutex->id]); > + > + WARN_ON(&mtx->mutex[mutex->id] != mutex); > + > + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, > + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), > + MTK_MUTEX_ENABLE, MTK_MUTEX_ENABLE); > +} > +EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq); > + > void mtk_mutex_disable(struct mtk_mutex *mutex) > { > struct mtk_mutex_ctx *mtx = container_of(mutex, struct > mtk_mutex_ctx, > @@ -575,6 +616,20 @@ void mtk_mutex_disable(struct mtk_mutex *mutex) > } > EXPORT_SYMBOL_GPL(mtk_mutex_disable); > > +void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex, > + struct mmsys_cmdq_cmd *cmd) > +{ > + struct mtk_mutex_ctx *mtx = container_of(mutex, struct > mtk_mutex_ctx, > + mutex[mutex->id]); > + > + WARN_ON(&mtx->mutex[mutex->id] != mutex); > + > + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, > + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), > + 0x0, MTK_MUTEX_ENABLE); > +} > +EXPORT_SYMBOL_GPL(mtk_mutex_disable_by_cmdq); > + > void mtk_mutex_acquire(struct mtk_mutex *mutex) > { > struct mtk_mutex_ctx *mtx = container_of(mutex, struct > mtk_mutex_ctx, > @@ -602,8 +657,8 @@ static int mtk_mutex_probe(struct platform_device > *pdev) > { > struct device *dev = &pdev->dev; > struct mtk_mutex_ctx *mtx; > - struct resource *regs; > - int i; > + struct resource *regs, addr; > + int i, ret; > > mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL); > if (!mtx) > @@ -623,6 +678,19 @@ static int mtk_mutex_probe(struct > platform_device *pdev) > } > } > > + if (of_address_to_resource(dev->of_node, 0, &addr) < 0) > + mtx->addr = 0L; > + else > + mtx->addr = addr.start; > + > + if (mtx->data->has_gce_client_reg) { > + ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0); Add gce client reg in binding document [1] [1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml?h=next-20220302 Regards, CK > + if (ret) { > + dev_err(dev, "No mediatek,gce-client-reg!\n"); > + return ret; > + } > + } > + > regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); > mtx->regs = devm_ioremap_resource(dev, regs); > if (IS_ERR(mtx->regs)) { > diff --git a/include/linux/soc/mediatek/mtk-mutex.h > b/include/linux/soc/mediatek/mtk-mutex.h > index b2608f4220ee..05de7ad4a124 100644 > --- a/include/linux/soc/mediatek/mtk-mutex.h > +++ b/include/linux/soc/mediatek/mtk-mutex.h > @@ -17,8 +17,14 @@ int mtk_mutex_prepare(struct mtk_mutex *mutex); > void mtk_mutex_add_comp(struct mtk_mutex *mutex, > enum mtk_ddp_comp_id id); > u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum > mtk_mdp_comp_id id); > +void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod, > + struct mmsys_cmdq_cmd *cmd); > void mtk_mutex_enable(struct mtk_mutex *mutex); > +void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, > + struct mmsys_cmdq_cmd *cmd); > void mtk_mutex_disable(struct mtk_mutex *mutex); > +void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex, > + struct mmsys_cmdq_cmd *cmd); > void mtk_mutex_remove_comp(struct mtk_mutex *mutex, > enum mtk_ddp_comp_id id); > void mtk_mutex_unprepare(struct mtk_mutex *mutex);
On Thu, 2022-03-03 at 18:01 +0800, CK Hu wrote: > Hi, Moudy: > > On Tue, 2022-03-01 at 18:02 +0800, Moudy Ho wrote: > > Considering that some functions have timing requirements > > in specific situation, this patch adds several interface that > > operate registers by CMDQ. > > > > Signed-off-by: Moudy Ho <moudy.ho@mediatek.com> > > Reviewed-by: AngeloGioacchino Del Regno < > > angelogioacchino.delregno@collabora.com> > > --- > > drivers/soc/mediatek/mtk-mutex.c | 72 > > +++++++++++++++++++++++++- > > include/linux/soc/mediatek/mtk-mutex.h | 6 +++ > > 2 files changed, 76 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/soc/mediatek/mtk-mutex.c > > b/drivers/soc/mediatek/mtk-mutex.c > > index a6268ecde240..a45864183cd1 100644 > > --- a/drivers/soc/mediatek/mtk-mutex.c > > +++ b/drivers/soc/mediatek/mtk-mutex.c > > @@ -7,10 +7,14 @@ (snip) > > + > > void mtk_mutex_enable(struct mtk_mutex *mutex) > > { > > struct mtk_mutex_ctx *mtx = container_of(mutex, struct > > mtk_mutex_ctx, > > @@ -564,6 +591,20 @@ void mtk_mutex_enable(struct mtk_mutex *mutex) > > } > > EXPORT_SYMBOL_GPL(mtk_mutex_enable); > > > > +void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, > > + struct mmsys_cmdq_cmd *cmd) > > There are 10 mutex and you could bind each pipeline to one mutex and > always enable it. I think it's not necessary to frequently > enable/disable mutex. Hi CK, Due to HW limitations, MDP is necessary to enable MUTEX in each frame for SOF triggering and cooperate with CMDQ control to reduce the amount of interrupts generated(also, reduce frame latency). Thanks & Regards, Moudy Ho > > +{ > > + struct mtk_mutex_ctx *mtx = container_of(mutex, struct > > mtk_mutex_ctx, > > + mutex[mutex->id]); > > + > > + WARN_ON(&mtx->mutex[mutex->id] != mutex); > > + > > + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, > > + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), > > + MTK_MUTEX_ENABLE, MTK_MUTEX_ENABLE); > > +} > > +EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq); > > + > > void mtk_mutex_disable(struct mtk_mutex *mutex) > > { > > struct mtk_mutex_ctx *mtx = container_of(mutex, struct > > mtk_mutex_ctx, > > @@ -575,6 +616,20 @@ void mtk_mutex_disable(struct mtk_mutex > > *mutex) > > } > > EXPORT_SYMBOL_GPL(mtk_mutex_disable); > > > > +void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex, > > + struct mmsys_cmdq_cmd *cmd) > > +{ > > + struct mtk_mutex_ctx *mtx = container_of(mutex, struct > > mtk_mutex_ctx, > > + mutex[mutex->id]); > > + > > + WARN_ON(&mtx->mutex[mutex->id] != mutex); > > + > > + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, > > + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), > > + 0x0, MTK_MUTEX_ENABLE); > > +} > > +EXPORT_SYMBOL_GPL(mtk_mutex_disable_by_cmdq); > > + > > void mtk_mutex_acquire(struct mtk_mutex *mutex) > > { > > struct mtk_mutex_ctx *mtx = container_of(mutex, struct > > mtk_mutex_ctx, > > @@ -602,8 +657,8 @@ static int mtk_mutex_probe(struct > > platform_device > > *pdev) > > { > > struct device *dev = &pdev->dev; > > struct mtk_mutex_ctx *mtx; > > - struct resource *regs; > > - int i; > > + struct resource *regs, addr; > > + int i, ret; > > > > mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL); > > if (!mtx) > > @@ -623,6 +678,19 @@ static int mtk_mutex_probe(struct > > platform_device *pdev) > > } > > } > > > > + if (of_address_to_resource(dev->of_node, 0, &addr) < 0) > > + mtx->addr = 0L; > > + else > > + mtx->addr = addr.start; > > + > > + if (mtx->data->has_gce_client_reg) { > > + ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0); > > Add gce client reg in binding document [1] > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml?h=next-20220302 > > Regards, > CK Thanks for the reminder, I will fill in the missing parts in the next version. > > + if (ret) { > > + dev_err(dev, "No mediatek,gce-client-reg!\n"); > > + return ret; > > + } > > + } > > + > > regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > mtx->regs = devm_ioremap_resource(dev, regs); > > if (IS_ERR(mtx->regs)) { > > diff --git a/include/linux/soc/mediatek/mtk-mutex.h > > b/include/linux/soc/mediatek/mtk-mutex.h > > index b2608f4220ee..05de7ad4a124 100644 > > --- a/include/linux/soc/mediatek/mtk-mutex.h > > +++ b/include/linux/soc/mediatek/mtk-mutex.h > > @@ -17,8 +17,14 @@ int mtk_mutex_prepare(struct mtk_mutex *mutex); > > void mtk_mutex_add_comp(struct mtk_mutex *mutex, > > enum mtk_ddp_comp_id id); > > u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum > > mtk_mdp_comp_id id); > > +void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod, > > + struct mmsys_cmdq_cmd *cmd); > > void mtk_mutex_enable(struct mtk_mutex *mutex); > > +void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, > > + struct mmsys_cmdq_cmd *cmd); > > void mtk_mutex_disable(struct mtk_mutex *mutex); > > +void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex, > > + struct mmsys_cmdq_cmd *cmd); > > void mtk_mutex_remove_comp(struct mtk_mutex *mutex, > > enum mtk_ddp_comp_id id); > > void mtk_mutex_unprepare(struct mtk_mutex *mutex); > >
diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index a6268ecde240..a45864183cd1 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -7,10 +7,14 @@ #include <linux/iopoll.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/soc/mediatek/mtk-mmsys.h> #include <linux/soc/mediatek/mtk-mutex.h> +#include <linux/soc/mediatek/mtk-cmdq.h> + +#define MTK_MUTEX_ENABLE BIT(0) #define MT2701_MUTEX0_MOD0 0x2c #define MT2701_MUTEX0_SOF0 0x30 @@ -173,6 +177,7 @@ struct mtk_mutex_data { const unsigned int mutex_mdp_mod_mask; const unsigned int mutex_mdp_sof_mask; const bool no_clk; + const bool has_gce_client_reg; }; struct mtk_mutex_ctx { @@ -181,6 +186,8 @@ struct mtk_mutex_ctx { void __iomem *regs; struct mtk_mutex mutex[10]; const struct mtk_mutex_data *data; + phys_addr_t addr; + struct cmdq_client_reg cmdq_reg; }; static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { @@ -374,6 +381,7 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { .mutex_mdp_mod_mask = MT8183_MUTEX_MDP_MOD_MASK, .mutex_mdp_sof_mask = MT8183_MUTEX_MDP_SOF_MASK, .no_clk = true, + .has_gce_client_reg = true, }; static const struct mtk_mutex_data mt8186_mutex_driver_data = { @@ -553,6 +561,25 @@ u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id) } EXPORT_SYMBOL_GPL(mtk_mutex_get_mdp_mod); +void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod, + struct mmsys_cmdq_cmd *cmd) +{ + struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, + mutex[mutex->id]); + unsigned int offset; + + WARN_ON(&mtx->mutex[mutex->id] != mutex); + + offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, mutex->id); + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset, + mod, mtx->data->mutex_mdp_mod_mask); + + offset = DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id); + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset, + 0, mtx->data->mutex_mdp_sof_mask); +} +EXPORT_SYMBOL_GPL(mtk_mutex_add_mod_by_cmdq); + void mtk_mutex_enable(struct mtk_mutex *mutex) { struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, @@ -564,6 +591,20 @@ void mtk_mutex_enable(struct mtk_mutex *mutex) } EXPORT_SYMBOL_GPL(mtk_mutex_enable); +void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, + struct mmsys_cmdq_cmd *cmd) +{ + struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, + mutex[mutex->id]); + + WARN_ON(&mtx->mutex[mutex->id] != mutex); + + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), + MTK_MUTEX_ENABLE, MTK_MUTEX_ENABLE); +} +EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq); + void mtk_mutex_disable(struct mtk_mutex *mutex) { struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, @@ -575,6 +616,20 @@ void mtk_mutex_disable(struct mtk_mutex *mutex) } EXPORT_SYMBOL_GPL(mtk_mutex_disable); +void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex, + struct mmsys_cmdq_cmd *cmd) +{ + struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, + mutex[mutex->id]); + + WARN_ON(&mtx->mutex[mutex->id] != mutex); + + cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), + 0x0, MTK_MUTEX_ENABLE); +} +EXPORT_SYMBOL_GPL(mtk_mutex_disable_by_cmdq); + void mtk_mutex_acquire(struct mtk_mutex *mutex) { struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, @@ -602,8 +657,8 @@ static int mtk_mutex_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mtk_mutex_ctx *mtx; - struct resource *regs; - int i; + struct resource *regs, addr; + int i, ret; mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL); if (!mtx) @@ -623,6 +678,19 @@ static int mtk_mutex_probe(struct platform_device *pdev) } } + if (of_address_to_resource(dev->of_node, 0, &addr) < 0) + mtx->addr = 0L; + else + mtx->addr = addr.start; + + if (mtx->data->has_gce_client_reg) { + ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0); + if (ret) { + dev_err(dev, "No mediatek,gce-client-reg!\n"); + return ret; + } + } + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); mtx->regs = devm_ioremap_resource(dev, regs); if (IS_ERR(mtx->regs)) { diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h index b2608f4220ee..05de7ad4a124 100644 --- a/include/linux/soc/mediatek/mtk-mutex.h +++ b/include/linux/soc/mediatek/mtk-mutex.h @@ -17,8 +17,14 @@ int mtk_mutex_prepare(struct mtk_mutex *mutex); void mtk_mutex_add_comp(struct mtk_mutex *mutex, enum mtk_ddp_comp_id id); u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id); +void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod, + struct mmsys_cmdq_cmd *cmd); void mtk_mutex_enable(struct mtk_mutex *mutex); +void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, + struct mmsys_cmdq_cmd *cmd); void mtk_mutex_disable(struct mtk_mutex *mutex); +void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex, + struct mmsys_cmdq_cmd *cmd); void mtk_mutex_remove_comp(struct mtk_mutex *mutex, enum mtk_ddp_comp_id id); void mtk_mutex_unprepare(struct mtk_mutex *mutex);