Message ID | 20250110-drm-s4-v1-3-cbc2d5edaae8@amlogic.com (mailing list archive) |
---|---|
State | New |
Delegated to: | Neil Armstrong |
Headers | show |
Series | Subject: [PATCH 00/11] Add DRM support for Amlogic S4 | expand |
On Fri 10 Jan 2025 at 13:39, Ao Xu via B4 Relay <devnull+ao.xu.amlogic.com@kernel.org> wrote: > From: Ao Xu <ao.xu@amlogic.com> > > Add S4 compatible for DRM driver. This update driver logic to support > S4-specific configurations. This also add vpu clock operation in > bind, suspend, resume, shutdown stage. > > Signed-off-by: Ao Xu <ao.xu@amlogic.com> > --- > drivers/gpu/drm/meson/meson_drv.c | 127 +++++++++++++++++++++++++++++++++++++- > drivers/gpu/drm/meson/meson_drv.h | 6 ++ > 2 files changed, 132 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c > index 81d2ee37e7732dca89d02347b9c972300b38771a..d28094efeb137ae0b9990ab3608825d563358dba 100644 > --- a/drivers/gpu/drm/meson/meson_drv.c > +++ b/drivers/gpu/drm/meson/meson_drv.c > @@ -11,6 +11,7 @@ > #include <linux/aperture.h> > #include <linux/component.h> > #include <linux/module.h> > +#include <linux/clk.h> > #include <linux/of_graph.h> > #include <linux/sys_soc.h> > #include <linux/platform_device.h> > @@ -160,6 +161,34 @@ static void meson_vpu_init(struct meson_drm *priv) > writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); > } > > +static void meson_setup_clk(struct meson_drm *priv, bool enable) > +{ > + int ret; > + > + if (!priv || !priv->vpu_clk || !priv->vapb_clk) > + return; > + > + if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4)) > + return; > + > + if (enable) { > + ret = clk_prepare_enable(priv->vpu_clk); > + if (ret) { > + dev_err(priv->dev, "Failed to set vpu clk\n"); > + return; > + } > + ret = clk_prepare_enable(priv->vapb_clk); > + if (ret) { > + dev_err(priv->dev, "Failed to Set vapb clk\n"); > + clk_disable_unprepare(priv->vpu_clk); > + return; > + } > + } else { > + clk_disable_unprepare(priv->vpu_clk); > + clk_disable_unprepare(priv->vapb_clk); > + } > +} > + > struct meson_drm_soc_attr { > struct meson_drm_soc_limits limits; > const struct soc_device_attribute *attrs; > @@ -241,6 +270,83 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) > goto free_drm; > } > > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4)) { > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sysctrl"); > + if (!res) { > + ret = -EINVAL; > + goto free_drm; > + } > + /* Simply ioremap since it may be a shared register zone */ This comment, the name of the zone and even the usage you are making of it clearly show this is repeating the error of past, directly accessing improperly shared registers which should otherwise have been implemented as proper controller using the kernel available framework, such PD, phys, clock, reset, etc ... Worse, it gets encoded into the dt binding, making extremely difficult to fix later on. > + regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (!regs) { > + ret = -EADDRNOTAVAIL; > + goto free_drm; > + } > + > + priv->sysctrl = devm_regmap_init_mmio(dev, regs, > + &meson_regmap_config); > + if (IS_ERR(priv->sysctrl)) { > + dev_err(&pdev->dev, "Couldn't create the SYSCTRL regmap\n"); > + ret = PTR_ERR(priv->sysctrl); > + goto free_drm; > + } > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clkctrl"); > + if (!res) { > + ret = -EINVAL; > + goto free_drm; > + } > + /* Simply ioremap since it may be a shared register zone */ > + regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (!regs) { > + ret = -EADDRNOTAVAIL; > + goto free_drm; > + } > + > + priv->clkctrl = devm_regmap_init_mmio(dev, regs, > + &meson_regmap_config); > + if (IS_ERR(priv->clkctrl)) { > + dev_err(&pdev->dev, "Couldn't create the clkctrl regmap\n"); > + ret = PTR_ERR(priv->clkctrl); > + goto free_drm; > + } > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrctrl"); > + if (!res) { > + ret = -EINVAL; > + goto free_drm; > + } > + /* Simply ioremap since it may be a shared register zone */ > + regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (!regs) { > + ret = -EADDRNOTAVAIL; > + goto free_drm; > + } > + > + priv->pwrctrl = devm_regmap_init_mmio(dev, regs, > + &meson_regmap_config); > + if (IS_ERR(priv->pwrctrl)) { > + dev_err(&pdev->dev, "Couldn't create the pwrctrl regmap\n"); > + ret = PTR_ERR(priv->pwrctrl); > + goto free_drm; > + } > + > + priv->vpu_clk = devm_clk_get(&pdev->dev, "vpu"); > + if (IS_ERR(priv->vpu_clk)) { > + dev_err(&pdev->dev, "vpu clock request failed\n"); > + ret = PTR_ERR(priv->vpu_clk); > + goto free_drm; > + } > + > + priv->vapb_clk = devm_clk_get(&pdev->dev, "vapb"); > + if (IS_ERR(priv->vapb_clk)) { > + dev_err(&pdev->dev, "vapb clock request failed\n"); > + ret = PTR_ERR(priv->vapb_clk); > + goto free_drm; > + } > + meson_setup_clk(priv, true); > + } > + > priv->canvas = meson_canvas_get(dev); > if (IS_ERR(priv->canvas)) { > ret = PTR_ERR(priv->canvas); > @@ -424,12 +530,21 @@ static const struct component_master_ops meson_drv_master_ops = { > > static int __maybe_unused meson_drv_pm_suspend(struct device *dev) > { > + int ret; > struct meson_drm *priv = dev_get_drvdata(dev); > > if (!priv) > return 0; > > - return drm_mode_config_helper_suspend(priv->drm); > + ret = drm_mode_config_helper_suspend(priv->drm); > + if (unlikely(ret)) { > + drm_err(dev, "suspend error: %d", ret); > + return ret; > + } > + > + meson_setup_clk(priv, false); > + > + return ret; > } > > static int __maybe_unused meson_drv_pm_resume(struct device *dev) > @@ -439,6 +554,7 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev) > if (!priv) > return 0; > > + meson_setup_clk(priv, true); > meson_vpu_init(priv); > meson_venc_init(priv); > meson_vpp_init(priv); > @@ -458,6 +574,7 @@ static void meson_drv_shutdown(struct platform_device *pdev) > > drm_kms_helper_poll_fini(priv->drm); > drm_atomic_helper_shutdown(priv->drm); > + meson_setup_clk(priv, false); > } > > /* > @@ -471,6 +588,7 @@ static const struct of_device_id components_dev_match[] = { > { .compatible = "amlogic,meson-gxl-dw-hdmi" }, > { .compatible = "amlogic,meson-gxm-dw-hdmi" }, > { .compatible = "amlogic,meson-g12a-dw-hdmi" }, > + { .compatible = "amlogic,meson-s4-dw-hdmi" }, > {} > }; > > @@ -539,6 +657,11 @@ static struct meson_drm_match_data meson_drm_g12a_data = { > .afbcd_ops = &meson_afbcd_g12a_ops, > }; > > +static struct meson_drm_match_data meson_drm_s4_data = { > + .compat = VPU_COMPATIBLE_S4, > + .afbcd_ops = &meson_afbcd_g12a_ops, > +}; > + > static const struct of_device_id dt_match[] = { > { .compatible = "amlogic,meson-gxbb-vpu", > .data = (void *)&meson_drm_gxbb_data }, > @@ -548,6 +671,8 @@ static const struct of_device_id dt_match[] = { > .data = (void *)&meson_drm_gxm_data }, > { .compatible = "amlogic,meson-g12a-vpu", > .data = (void *)&meson_drm_g12a_data }, > + { .compatible = "amlogic,meson-s4-vpu", > + .data = (void *)&meson_drm_s4_data }, > {} > }; > MODULE_DEVICE_TABLE(of, dt_match); > diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h > index 3f9345c14f31c13b071f420533fe8a450d3e0f36..c801a2e3e55a054247710aebae5602e44c9e1624 100644 > --- a/drivers/gpu/drm/meson/meson_drv.h > +++ b/drivers/gpu/drm/meson/meson_drv.h > @@ -22,6 +22,7 @@ enum vpu_compatible { > VPU_COMPATIBLE_GXL = 1, > VPU_COMPATIBLE_GXM = 2, > VPU_COMPATIBLE_G12A = 3, > + VPU_COMPATIBLE_S4 = 4, > }; > > enum { > @@ -45,6 +46,11 @@ struct meson_drm { > enum vpu_compatible compat; > void __iomem *io_base; > struct regmap *hhi; > + struct regmap *sysctrl; > + struct regmap *clkctrl; > + struct regmap *pwrctrl; > + struct clk *vpu_clk; > + struct clk *vapb_clk; > int vsync_irq; > > struct meson_canvas *canvas;
Hi Ao, kernel test robot noticed the following build errors: [auto build test ERROR on 6ecd20965bdc21b265a0671ccf36d9ad8043f5ab] url: https://github.com/intel-lab-lkp/linux/commits/Ao-Xu-via-B4-Relay/dt-bindings-display-meson-dw-hdmi-Add-compatible-for-S4-HDMI-controller/20250110-134113 base: 6ecd20965bdc21b265a0671ccf36d9ad8043f5ab patch link: https://lore.kernel.org/r/20250110-drm-s4-v1-3-cbc2d5edaae8%40amlogic.com patch subject: [PATCH 03/11] drm: meson: add S4 compatible for DRM driver config: csky-randconfig-002-20250111 (https://download.01.org/0day-ci/archive/20250111/202501111433.iVcR3vZY-lkp@intel.com/config) compiler: csky-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250111/202501111433.iVcR3vZY-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501111433.iVcR3vZY-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from include/linux/device.h:15, from include/linux/sys_soc.h:9, from drivers/gpu/drm/meson/meson_drv.c:16: drivers/gpu/drm/meson/meson_drv.c: In function 'meson_drv_pm_suspend': >> include/drm/drm_print.h:588:42: error: 'struct device' has no member named 'dev'; did you mean 'devt'? 588 | dev_##level##type((drm) ? (drm)->dev : NULL, "[drm] " fmt, ##__VA_ARGS__) | ^~~ include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/drm/drm_print.h:588:9: note: in expansion of macro 'dev_err' 588 | dev_##level##type((drm) ? (drm)->dev : NULL, "[drm] " fmt, ##__VA_ARGS__) | ^~~~ include/drm/drm_print.h:601:9: note: in expansion of macro '__drm_printk' 601 | __drm_printk((drm), err,, "*ERROR* " fmt, ##__VA_ARGS__) | ^~~~~~~~~~~~ drivers/gpu/drm/meson/meson_drv.c:541:17: note: in expansion of macro 'drm_err' 541 | drm_err(dev, "suspend error: %d", ret); | ^~~~~~~ -- In file included from include/linux/device.h:15, from include/linux/sys_soc.h:9, from meson_drv.c:16: meson_drv.c: In function 'meson_drv_pm_suspend': >> include/drm/drm_print.h:588:42: error: 'struct device' has no member named 'dev'; did you mean 'devt'? 588 | dev_##level##type((drm) ? (drm)->dev : NULL, "[drm] " fmt, ##__VA_ARGS__) | ^~~ include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/drm/drm_print.h:588:9: note: in expansion of macro 'dev_err' 588 | dev_##level##type((drm) ? (drm)->dev : NULL, "[drm] " fmt, ##__VA_ARGS__) | ^~~~ include/drm/drm_print.h:601:9: note: in expansion of macro '__drm_printk' 601 | __drm_printk((drm), err,, "*ERROR* " fmt, ##__VA_ARGS__) | ^~~~~~~~~~~~ meson_drv.c:541:17: note: in expansion of macro 'drm_err' 541 | drm_err(dev, "suspend error: %d", ret); | ^~~~~~~ vim +588 include/drm/drm_print.h e820f52577b14c Jim Cromie 2022-09-11 548 02c9656b2f0d69 Haneen Mohammed 2017-10-17 549 /** b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 550 * DRM_DEV_DEBUG() - Debug output for generic drm code 02c9656b2f0d69 Haneen Mohammed 2017-10-17 551 * 306589856399e1 Douglas Anderson 2021-09-21 552 * NOTE: this is deprecated in favor of drm_dbg_core(). 306589856399e1 Douglas Anderson 2021-09-21 553 * 091756bbb1a961 Haneen Mohammed 2017-10-17 554 * @dev: device pointer 091756bbb1a961 Haneen Mohammed 2017-10-17 555 * @fmt: printf() like format string. 02c9656b2f0d69 Haneen Mohammed 2017-10-17 556 */ db87086492581c Joe Perches 2018-03-16 557 #define DRM_DEV_DEBUG(dev, fmt, ...) \ db87086492581c Joe Perches 2018-03-16 558 drm_dev_dbg(dev, DRM_UT_CORE, fmt, ##__VA_ARGS__) b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 559 /** b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 560 * DRM_DEV_DEBUG_DRIVER() - Debug output for vendor specific part of the driver b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 561 * 306589856399e1 Douglas Anderson 2021-09-21 562 * NOTE: this is deprecated in favor of drm_dbg() or dev_dbg(). 306589856399e1 Douglas Anderson 2021-09-21 563 * b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 564 * @dev: device pointer b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 565 * @fmt: printf() like format string. b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 566 */ db87086492581c Joe Perches 2018-03-16 567 #define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \ db87086492581c Joe Perches 2018-03-16 568 drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 569 /** b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 570 * DRM_DEV_DEBUG_KMS() - Debug output for modesetting code b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 571 * 306589856399e1 Douglas Anderson 2021-09-21 572 * NOTE: this is deprecated in favor of drm_dbg_kms(). 306589856399e1 Douglas Anderson 2021-09-21 573 * b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 574 * @dev: device pointer b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 575 * @fmt: printf() like format string. b52817e9de06a3 Mauro Carvalho Chehab 2020-10-27 576 */ db87086492581c Joe Perches 2018-03-16 577 #define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \ db87086492581c Joe Perches 2018-03-16 578 drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__) a18b21929453af Lyude Paul 2018-07-16 579 fb6c7ab8718eb2 Jani Nikula 2019-12-10 580 /* fb6c7ab8718eb2 Jani Nikula 2019-12-10 581 * struct drm_device based logging fb6c7ab8718eb2 Jani Nikula 2019-12-10 582 * fb6c7ab8718eb2 Jani Nikula 2019-12-10 583 * Prefer drm_device based logging over device or prink based logging. fb6c7ab8718eb2 Jani Nikula 2019-12-10 584 */ fb6c7ab8718eb2 Jani Nikula 2019-12-10 585 fb6c7ab8718eb2 Jani Nikula 2019-12-10 586 /* Helper for struct drm_device based logging. */ fb6c7ab8718eb2 Jani Nikula 2019-12-10 587 #define __drm_printk(drm, level, type, fmt, ...) \ e04d24c4e8062b Luben Tuikov 2023-11-16 @588 dev_##level##type((drm) ? (drm)->dev : NULL, "[drm] " fmt, ##__VA_ARGS__) fb6c7ab8718eb2 Jani Nikula 2019-12-10 589 fb6c7ab8718eb2 Jani Nikula 2019-12-10 590
Hi Ao, kernel test robot noticed the following build errors: [auto build test ERROR on 6ecd20965bdc21b265a0671ccf36d9ad8043f5ab] url: https://github.com/intel-lab-lkp/linux/commits/Ao-Xu-via-B4-Relay/dt-bindings-display-meson-dw-hdmi-Add-compatible-for-S4-HDMI-controller/20250110-134113 base: 6ecd20965bdc21b265a0671ccf36d9ad8043f5ab patch link: https://lore.kernel.org/r/20250110-drm-s4-v1-3-cbc2d5edaae8%40amlogic.com patch subject: [PATCH 03/11] drm: meson: add S4 compatible for DRM driver config: arm64-randconfig-002-20250111 (https://download.01.org/0day-ci/archive/20250111/202501111505.wNSI9zrC-lkp@intel.com/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project f5cd181ffbb7cb61d582fe130d46580d5969d47a) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250111/202501111505.wNSI9zrC-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501111505.wNSI9zrC-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/gpu/drm/meson/meson_drv.c:541:3: error: no member named 'dev' in 'struct device'; did you mean 'devt'? 541 | drm_err(dev, "suspend error: %d", ret); | ^ include/drm/drm_print.h:601:2: note: expanded from macro 'drm_err' 601 | __drm_printk((drm), err,, "*ERROR* " fmt, ##__VA_ARGS__) | ^ include/drm/drm_print.h:588:35: note: expanded from macro '__drm_printk' 588 | dev_##level##type((drm) ? (drm)->dev : NULL, "[drm] " fmt, ##__VA_ARGS__) | ^ include/linux/device.h:794:10: note: 'devt' declared here 794 | dev_t devt; /* dev_t, creates the sysfs "dev" */ | ^ 1 error generated. vim +541 drivers/gpu/drm/meson/meson_drv.c 530 531 static int __maybe_unused meson_drv_pm_suspend(struct device *dev) 532 { 533 int ret; 534 struct meson_drm *priv = dev_get_drvdata(dev); 535 536 if (!priv) 537 return 0; 538 539 ret = drm_mode_config_helper_suspend(priv->drm); 540 if (unlikely(ret)) { > 541 drm_err(dev, "suspend error: %d", ret); 542 return ret; 543 } 544 545 meson_setup_clk(priv, false); 546 547 return ret; 548 } 549
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 81d2ee37e7732dca89d02347b9c972300b38771a..d28094efeb137ae0b9990ab3608825d563358dba 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -11,6 +11,7 @@ #include <linux/aperture.h> #include <linux/component.h> #include <linux/module.h> +#include <linux/clk.h> #include <linux/of_graph.h> #include <linux/sys_soc.h> #include <linux/platform_device.h> @@ -160,6 +161,34 @@ static void meson_vpu_init(struct meson_drm *priv) writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); } +static void meson_setup_clk(struct meson_drm *priv, bool enable) +{ + int ret; + + if (!priv || !priv->vpu_clk || !priv->vapb_clk) + return; + + if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4)) + return; + + if (enable) { + ret = clk_prepare_enable(priv->vpu_clk); + if (ret) { + dev_err(priv->dev, "Failed to set vpu clk\n"); + return; + } + ret = clk_prepare_enable(priv->vapb_clk); + if (ret) { + dev_err(priv->dev, "Failed to Set vapb clk\n"); + clk_disable_unprepare(priv->vpu_clk); + return; + } + } else { + clk_disable_unprepare(priv->vpu_clk); + clk_disable_unprepare(priv->vapb_clk); + } +} + struct meson_drm_soc_attr { struct meson_drm_soc_limits limits; const struct soc_device_attribute *attrs; @@ -241,6 +270,83 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) goto free_drm; } + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4)) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sysctrl"); + if (!res) { + ret = -EINVAL; + goto free_drm; + } + /* Simply ioremap since it may be a shared register zone */ + regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!regs) { + ret = -EADDRNOTAVAIL; + goto free_drm; + } + + priv->sysctrl = devm_regmap_init_mmio(dev, regs, + &meson_regmap_config); + if (IS_ERR(priv->sysctrl)) { + dev_err(&pdev->dev, "Couldn't create the SYSCTRL regmap\n"); + ret = PTR_ERR(priv->sysctrl); + goto free_drm; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clkctrl"); + if (!res) { + ret = -EINVAL; + goto free_drm; + } + /* Simply ioremap since it may be a shared register zone */ + regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!regs) { + ret = -EADDRNOTAVAIL; + goto free_drm; + } + + priv->clkctrl = devm_regmap_init_mmio(dev, regs, + &meson_regmap_config); + if (IS_ERR(priv->clkctrl)) { + dev_err(&pdev->dev, "Couldn't create the clkctrl regmap\n"); + ret = PTR_ERR(priv->clkctrl); + goto free_drm; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrctrl"); + if (!res) { + ret = -EINVAL; + goto free_drm; + } + /* Simply ioremap since it may be a shared register zone */ + regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!regs) { + ret = -EADDRNOTAVAIL; + goto free_drm; + } + + priv->pwrctrl = devm_regmap_init_mmio(dev, regs, + &meson_regmap_config); + if (IS_ERR(priv->pwrctrl)) { + dev_err(&pdev->dev, "Couldn't create the pwrctrl regmap\n"); + ret = PTR_ERR(priv->pwrctrl); + goto free_drm; + } + + priv->vpu_clk = devm_clk_get(&pdev->dev, "vpu"); + if (IS_ERR(priv->vpu_clk)) { + dev_err(&pdev->dev, "vpu clock request failed\n"); + ret = PTR_ERR(priv->vpu_clk); + goto free_drm; + } + + priv->vapb_clk = devm_clk_get(&pdev->dev, "vapb"); + if (IS_ERR(priv->vapb_clk)) { + dev_err(&pdev->dev, "vapb clock request failed\n"); + ret = PTR_ERR(priv->vapb_clk); + goto free_drm; + } + meson_setup_clk(priv, true); + } + priv->canvas = meson_canvas_get(dev); if (IS_ERR(priv->canvas)) { ret = PTR_ERR(priv->canvas); @@ -424,12 +530,21 @@ static const struct component_master_ops meson_drv_master_ops = { static int __maybe_unused meson_drv_pm_suspend(struct device *dev) { + int ret; struct meson_drm *priv = dev_get_drvdata(dev); if (!priv) return 0; - return drm_mode_config_helper_suspend(priv->drm); + ret = drm_mode_config_helper_suspend(priv->drm); + if (unlikely(ret)) { + drm_err(dev, "suspend error: %d", ret); + return ret; + } + + meson_setup_clk(priv, false); + + return ret; } static int __maybe_unused meson_drv_pm_resume(struct device *dev) @@ -439,6 +554,7 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev) if (!priv) return 0; + meson_setup_clk(priv, true); meson_vpu_init(priv); meson_venc_init(priv); meson_vpp_init(priv); @@ -458,6 +574,7 @@ static void meson_drv_shutdown(struct platform_device *pdev) drm_kms_helper_poll_fini(priv->drm); drm_atomic_helper_shutdown(priv->drm); + meson_setup_clk(priv, false); } /* @@ -471,6 +588,7 @@ static const struct of_device_id components_dev_match[] = { { .compatible = "amlogic,meson-gxl-dw-hdmi" }, { .compatible = "amlogic,meson-gxm-dw-hdmi" }, { .compatible = "amlogic,meson-g12a-dw-hdmi" }, + { .compatible = "amlogic,meson-s4-dw-hdmi" }, {} }; @@ -539,6 +657,11 @@ static struct meson_drm_match_data meson_drm_g12a_data = { .afbcd_ops = &meson_afbcd_g12a_ops, }; +static struct meson_drm_match_data meson_drm_s4_data = { + .compat = VPU_COMPATIBLE_S4, + .afbcd_ops = &meson_afbcd_g12a_ops, +}; + static const struct of_device_id dt_match[] = { { .compatible = "amlogic,meson-gxbb-vpu", .data = (void *)&meson_drm_gxbb_data }, @@ -548,6 +671,8 @@ static const struct of_device_id dt_match[] = { .data = (void *)&meson_drm_gxm_data }, { .compatible = "amlogic,meson-g12a-vpu", .data = (void *)&meson_drm_g12a_data }, + { .compatible = "amlogic,meson-s4-vpu", + .data = (void *)&meson_drm_s4_data }, {} }; MODULE_DEVICE_TABLE(of, dt_match); diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h index 3f9345c14f31c13b071f420533fe8a450d3e0f36..c801a2e3e55a054247710aebae5602e44c9e1624 100644 --- a/drivers/gpu/drm/meson/meson_drv.h +++ b/drivers/gpu/drm/meson/meson_drv.h @@ -22,6 +22,7 @@ enum vpu_compatible { VPU_COMPATIBLE_GXL = 1, VPU_COMPATIBLE_GXM = 2, VPU_COMPATIBLE_G12A = 3, + VPU_COMPATIBLE_S4 = 4, }; enum { @@ -45,6 +46,11 @@ struct meson_drm { enum vpu_compatible compat; void __iomem *io_base; struct regmap *hhi; + struct regmap *sysctrl; + struct regmap *clkctrl; + struct regmap *pwrctrl; + struct clk *vpu_clk; + struct clk *vapb_clk; int vsync_irq; struct meson_canvas *canvas;