The two VPUs inside IMX8MQ share the same control block which can be see
as a reset hardware block.
In order to be able to add the second VPU (for HECV decoding) it will be
more handy if the both VPU drivers instance don't have to share the
control block registers. This lead to implement it as an independ reset
driver and to change the VPU driver to use it.
Please note that this series break the compatibility between the DTB and
kernel. This break is limited to IMX8MQ SoC and is done when the driver
is still in staging directory.
version 3:
- Fix error in VPU example node
version 2:
- Document the change in VPU bindings
Benjamin Gaignard (5):
dt-bindings: reset: IMX8MQ VPU reset
dt-bindings: media: IMX8MQ VPU: document reset usage
reset: Add reset driver for IMX8MQ VPU block
media: hantro: Use reset driver
arm64: dts: imx8mq: Use reset driver for VPU hardware block
.../bindings/media/nxp,imx8mq-vpu.yaml | 14 +-
.../bindings/reset/fsl,imx8mq-vpu-reset.yaml | 54 ++++++
arch/arm64/boot/dts/freescale/imx8mq.dtsi | 31 +++-
drivers/reset/Kconfig | 8 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-imx8mq-vpu.c | 169 ++++++++++++++++++
drivers/staging/media/hantro/Kconfig | 1 +
drivers/staging/media/hantro/imx8m_vpu_hw.c | 61 ++-----
include/dt-bindings/reset/imx8mq-vpu-reset.h | 16 ++
9 files changed, 294 insertions(+), 61 deletions(-)
create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
create mode 100644 drivers/reset/reset-imx8mq-vpu.c
create mode 100644 include/dt-bindings/reset/imx8mq-vpu-reset.h
--
2.25.1
Document IMX8MQ VPU bindings to add the phandle to the reset driver.
Provide an independent reset driver allow to the both VPUs to share
their control/reset hardware block. The reset driver replace what
was previously done be using the 'ctrl' registers inside the driver.
This breaks the compatibility between DTB and kernel but the driver
is still in staging directory and limited to IMX8MQ SoC.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
version 3:
- Fix error in VPU example node
.../devicetree/bindings/media/nxp,imx8mq-vpu.yaml | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 762be3f96ce9..fd53a4e43572 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -18,13 +18,12 @@ properties:
const: nxp,imx8mq-vpu
reg:
- maxItems: 3
+ maxItems: 2
reg-names:
items:
- const: g1
- const: g2
- - const: ctrl
interrupts:
maxItems: 2
@@ -46,6 +45,9 @@ properties:
power-domains:
maxItems: 1
+ resets:
+ maxItems: 1
+
required:
- compatible
- reg
@@ -54,6 +56,7 @@ required:
- interrupt-names
- clocks
- clock-names
+ - resets
additionalProperties: false
@@ -61,13 +64,13 @@ examples:
- |
#include <dt-bindings/clock/imx8mq-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/reset/imx8mq-vpu-reset.h>
vpu: video-codec@38300000 {
compatible = "nxp,imx8mq-vpu";
reg = <0x38300000 0x10000>,
- <0x38310000 0x10000>,
- <0x38320000 0x10000>;
- reg-names = "g1", "g2", "ctrl";
+ <0x38310000 0x10000>;
+ reg-names = "g1", "g2";
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "g1", "g2";
@@ -76,4 +79,5 @@ examples:
<&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
clock-names = "g1", "g2", "bus";
power-domains = <&pgc_vpu>;
+ resets = <&vpu_reset IMX8MQ_RESET_VPU_RESET_G1>;
};
--
2.25.1
Rather use a reset like feature inside the driver use the reset
controller API to get the same result.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
drivers/staging/media/hantro/Kconfig | 1 +
drivers/staging/media/hantro/imx8m_vpu_hw.c | 61 ++++-----------------
2 files changed, 12 insertions(+), 50 deletions(-)
diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
index 5b6cf9f62b1a..dd1d4dde2658 100644
--- a/drivers/staging/media/hantro/Kconfig
+++ b/drivers/staging/media/hantro/Kconfig
@@ -20,6 +20,7 @@ config VIDEO_HANTRO_IMX8M
bool "Hantro VPU i.MX8M support"
depends on VIDEO_HANTRO
depends on ARCH_MXC || COMPILE_TEST
+ select RESET_VPU_IMX8MQ
default y
help
Enable support for i.MX8M SoCs.
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index c222de075ef4..d5b4312b9391 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -7,49 +7,12 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/reset.h>
#include "hantro.h"
#include "hantro_jpeg.h"
#include "hantro_g1_regs.h"
-#define CTRL_SOFT_RESET 0x00
-#define RESET_G1 BIT(1)
-#define RESET_G2 BIT(0)
-
-#define CTRL_CLOCK_ENABLE 0x04
-#define CLOCK_G1 BIT(1)
-#define CLOCK_G2 BIT(0)
-
-#define CTRL_G1_DEC_FUSE 0x08
-#define CTRL_G1_PP_FUSE 0x0c
-#define CTRL_G2_DEC_FUSE 0x10
-
-static void imx8m_soft_reset(struct hantro_dev *vpu, u32 reset_bits)
-{
- u32 val;
-
- /* Assert */
- val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
- val &= ~reset_bits;
- writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
-
- udelay(2);
-
- /* Release */
- val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
- val |= reset_bits;
- writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
-}
-
-static void imx8m_clk_enable(struct hantro_dev *vpu, u32 clock_bits)
-{
- u32 val;
-
- val = readl(vpu->ctrl_base + CTRL_CLOCK_ENABLE);
- val |= clock_bits;
- writel(val, vpu->ctrl_base + CTRL_CLOCK_ENABLE);
-}
-
static int imx8mq_runtime_resume(struct hantro_dev *vpu)
{
int ret;
@@ -60,13 +23,10 @@ static int imx8mq_runtime_resume(struct hantro_dev *vpu)
return ret;
}
- imx8m_soft_reset(vpu, RESET_G1 | RESET_G2);
- imx8m_clk_enable(vpu, CLOCK_G1 | CLOCK_G2);
+ ret = device_reset(vpu->dev);
+ if (ret)
+ dev_err(vpu->dev, "Failed to reset Hantro VPU\n");
- /* Set values of the fuse registers */
- writel(0xffffffff, vpu->ctrl_base + CTRL_G1_DEC_FUSE);
- writel(0xffffffff, vpu->ctrl_base + CTRL_G1_PP_FUSE);
- writel(0xffffffff, vpu->ctrl_base + CTRL_G2_DEC_FUSE);
clk_bulk_disable_unprepare(vpu->variant->num_clocks, vpu->clocks);
@@ -151,16 +111,17 @@ static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)
{
vpu->dec_base = vpu->reg_bases[0];
- vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];
return 0;
}
-static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
+static void imx8mq_vpu_reset(struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
+ int ret = device_reset(vpu->dev);
- imx8m_soft_reset(vpu, RESET_G1);
+ if (ret)
+ dev_err(vpu->dev, "Failed to reset Hantro VPU\n");
}
/*
@@ -170,19 +131,19 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {
[HANTRO_MODE_MPEG2_DEC] = {
.run = hantro_g1_mpeg2_dec_run,
- .reset = imx8m_vpu_g1_reset,
+ .reset = imx8mq_vpu_reset,
.init = hantro_mpeg2_dec_init,
.exit = hantro_mpeg2_dec_exit,
},
[HANTRO_MODE_VP8_DEC] = {
.run = hantro_g1_vp8_dec_run,
- .reset = imx8m_vpu_g1_reset,
+ .reset = imx8mq_vpu_reset,
.init = hantro_vp8_dec_init,
.exit = hantro_vp8_dec_exit,
},
[HANTRO_MODE_H264_DEC] = {
.run = hantro_g1_h264_dec_run,
- .reset = imx8m_vpu_g1_reset,
+ .reset = imx8mq_vpu_reset,
.init = hantro_h264_dec_init,
.exit = hantro_h264_dec_exit,
},
--
2.25.1
Document bindings for IMX8MQ VPU reset hardware block
Signed-off-by: Benjamin Gaignard <[email protected]>
---
.../bindings/reset/fsl,imx8mq-vpu-reset.yaml | 54 +++++++++++++++++++
include/dt-bindings/reset/imx8mq-vpu-reset.h | 16 ++++++
2 files changed, 70 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
create mode 100644 include/dt-bindings/reset/imx8mq-vpu-reset.h
diff --git a/Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml b/Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
new file mode 100644
index 000000000000..00020421c0e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/fsl,imx8mq-vpu-reset.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MQ VPU Reset Controller
+
+maintainers:
+ - Benjamin Gaignard <[email protected]>
+
+description: |
+ The VPU reset controller is used to reset the video processor
+ unit peripherals. Device nodes that need access to reset lines should
+ specify them as a reset phandle in their corresponding node as
+ specified in reset.txt.
+
+ For list of all valid reset indices see
+ <dt-bindings/reset/imx8mq-vpu-reset.h> for i.MX8MQ.
+
+properties:
+ compatible:
+ items:
+ - const: fsl,imx8mq-vpu-reset
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 3
+
+ '#reset-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/imx8mq-clock.h>
+
+ vpu-reset@38320000 {
+ compatible = "fsl,imx8mq-vpu-reset", "syscon";
+ reg = <0x38320000 0x10000>;
+ clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+ #reset-cells = <1>;
+ };
diff --git a/include/dt-bindings/reset/imx8mq-vpu-reset.h b/include/dt-bindings/reset/imx8mq-vpu-reset.h
new file mode 100644
index 000000000000..efcbe18177fe
--- /dev/null
+++ b/include/dt-bindings/reset/imx8mq-vpu-reset.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, Collabora
+ *
+ * i.MX7 System Reset Controller (SRC) driver
+ *
+ * Author: Benjamin Gaignard <[email protected]>
+ */
+
+#ifndef DT_BINDINGS_VPU_RESET_IMX8MQ
+#define DT_BINDINGS_VPU_RESET_IMX8MQ
+
+#define IMX8MQ_RESET_VPU_RESET_G1 0
+#define IMX8MQ_RESET_VPU_RESET_G2 1
+
+#endif
--
2.25.1
IMX8MQ SoC got a dedicated hardware block to reset the video processor
units (G1 and G2).
Signed-off-by: Benjamin Gaignard <[email protected]>
---
drivers/reset/Kconfig | 8 ++
drivers/reset/Makefile | 1 +
drivers/reset/reset-imx8mq-vpu.c | 169 +++++++++++++++++++++++++++++++
3 files changed, 178 insertions(+)
create mode 100644 drivers/reset/reset-imx8mq-vpu.c
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 71ab75a46491..fa95380b271a 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -80,6 +80,14 @@ config RESET_IMX7
help
This enables the reset controller driver for i.MX7 SoCs.
+config RESET_VPU_IMX8MQ
+ tristate "i.MX8MQ VPU Reset Driver"
+ depends on HAS_IOMEM
+ depends on (ARM64 && ARCH_MXC) || COMPILE_TEST
+ select MFD_SYSCON
+ help
+ This enables the VPU reset controller driver for i.MX8MQ SoCs.
+
config RESET_INTEL_GW
bool "Intel Reset Controller Driver"
depends on OF && HAS_IOMEM
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 1054123fd187..6007e0cdfc05 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
+obj-$(CONFIG_RESET_VPU_IMX8MQ) += reset-imx8mq-vpu.o
obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
diff --git a/drivers/reset/reset-imx8mq-vpu.c b/drivers/reset/reset-imx8mq-vpu.c
new file mode 100644
index 000000000000..14c589f19266
--- /dev/null
+++ b/drivers/reset/reset-imx8mq-vpu.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, Collabora
+ *
+ * i.MX8MQ VPU Reset Controller driver
+ *
+ * Author: Benjamin Gaignard <[email protected]>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+#include <dt-bindings/reset/imx8mq-vpu-reset.h>
+
+#define CTRL_SOFT_RESET 0x00
+#define RESET_G1 ((u32)BIT(1))
+#define RESET_G2 ((u32)BIT(0))
+
+#define CTRL_ENABLE 0x04
+#define ENABLE_G1 BIT(1)
+#define ENABLE_G2 BIT(0)
+
+#define CTRL_G1_DEC_FUSE 0x08
+#define CTRL_G1_PP_FUSE 0x0c
+#define CTRL_G2_DEC_FUSE 0x10
+
+struct imx8mq_vpu_reset {
+ struct reset_controller_dev rcdev;
+ struct regmap *regmap;
+ struct clk_bulk_data *clocks;
+ int num_clocks;
+ struct device *dev;
+};
+
+static inline struct imx8mq_vpu_reset *to_imx8mq_vpu_reset(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct imx8mq_vpu_reset, rcdev);
+}
+
+static int imx8mq_vpu_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct imx8mq_vpu_reset *reset = to_imx8mq_vpu_reset(rcdev);
+ int ret = -EINVAL;
+
+ ret = clk_bulk_prepare_enable(reset->num_clocks, reset->clocks);
+ if (ret) {
+ dev_err(reset->dev, "Failed to prepare clocks\n");
+ return ret;
+ }
+
+ switch (id) {
+ case IMX8MQ_RESET_VPU_RESET_G1:
+ ret = regmap_update_bits(reset->regmap, CTRL_SOFT_RESET, RESET_G1, ~RESET_G1);
+ ret |= regmap_update_bits(reset->regmap, CTRL_ENABLE, ENABLE_G1, ENABLE_G1);
+ break;
+ case IMX8MQ_RESET_VPU_RESET_G2:
+ ret = regmap_update_bits(reset->regmap, CTRL_SOFT_RESET, RESET_G2, ~RESET_G2);
+ ret |= regmap_update_bits(reset->regmap, CTRL_ENABLE, ENABLE_G2, ENABLE_G2);
+ break;
+ }
+
+ /* Set values of the fuse registers */
+ ret |= regmap_write(reset->regmap, CTRL_G1_DEC_FUSE, 0xffffffff);
+ ret |= regmap_write(reset->regmap, CTRL_G1_PP_FUSE, 0xffffffff);
+ ret |= regmap_write(reset->regmap, CTRL_G2_DEC_FUSE, 0xffffffff);
+
+ clk_bulk_disable_unprepare(reset->num_clocks, reset->clocks);
+
+ return ret;
+}
+
+static int imx8mq_vpu_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct imx8mq_vpu_reset *reset = to_imx8mq_vpu_reset(rcdev);
+ int ret;
+
+ ret = clk_bulk_prepare_enable(reset->num_clocks, reset->clocks);
+ if (ret) {
+ dev_err(reset->dev, "Failed to prepare clocks\n");
+ return ret;
+ }
+
+ switch (id) {
+ case IMX8MQ_RESET_VPU_RESET_G1:
+ return regmap_update_bits(reset->regmap, CTRL_SOFT_RESET, RESET_G1, RESET_G1);
+ case IMX8MQ_RESET_VPU_RESET_G2:
+ return regmap_update_bits(reset->regmap, CTRL_SOFT_RESET, RESET_G2, RESET_G2);
+ }
+
+ clk_bulk_disable_unprepare(reset->num_clocks, reset->clocks);
+
+ return -EINVAL;
+}
+
+static int imx8mq_vpu_reset_dev(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = imx8mq_vpu_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ udelay(2);
+
+ return imx8mq_vpu_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops imx8mq_vpu_reset_ops = {
+ .reset = imx8mq_vpu_reset_dev,
+ .assert = imx8mq_vpu_reset_assert,
+ .deassert = imx8mq_vpu_reset_deassert,
+};
+
+static int imx8mq_vpu_reset_probe(struct platform_device *pdev)
+{
+ struct imx8mq_vpu_reset *reset;
+ struct device *dev = &pdev->dev;
+ struct regmap_config config = { .name = "vpu-reset" };
+
+ reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
+ if (!reset)
+ return -ENOMEM;
+
+ reset->regmap = device_node_to_regmap(dev->of_node);
+ if (IS_ERR(reset->regmap)) {
+ dev_err(dev, "Unable to get imx8mq-vpu-reset regmap");
+ return PTR_ERR(reset->regmap);
+ }
+ regmap_attach_dev(dev, reset->regmap, &config);
+
+ reset->num_clocks = devm_clk_bulk_get_all(dev, &reset->clocks);
+ if (!reset->num_clocks)
+ return -EINVAL;
+
+ reset->rcdev.owner = THIS_MODULE;
+ reset->rcdev.nr_resets = 2;
+ reset->rcdev.ops = &imx8mq_vpu_reset_ops;
+ reset->rcdev.of_node = dev->of_node;
+ reset->dev = dev;
+
+ return devm_reset_controller_register(dev, &reset->rcdev);
+}
+
+static const struct of_device_id imx8mq_vpu_reset_dt_ids[] = {
+ { .compatible = "fsl,imx8mq-vpu-reset",},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mq_vpu_reset_dt_ids);
+
+static struct platform_driver imx8mq_vpu_reset_driver = {
+ .probe = imx8mq_vpu_reset_probe,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = imx8mq_vpu_reset_dt_ids,
+ },
+};
+module_platform_driver(imx8mq_vpu_reset_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <[email protected]>");
+MODULE_DESCRIPTION("NXP i.MX8MQ VPU reset driver");
+MODULE_LICENSE("GPL v2");
--
2.25.1
Add a vpu reset hardware block node.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
arch/arm64/boot/dts/freescale/imx8mq.dtsi | 31 ++++++++++++++++++-----
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index a841a023e8e0..d9d9efc8592d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -7,6 +7,7 @@
#include <dt-bindings/clock/imx8mq-clock.h>
#include <dt-bindings/power/imx8mq-power.h>
#include <dt-bindings/reset/imx8mq-reset.h>
+#include <dt-bindings/reset/imx8mq-vpu-reset.h>
#include <dt-bindings/gpio/gpio.h>
#include "dt-bindings/input/input.h"
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -1267,19 +1268,36 @@ usb3_phy1: usb-phy@382f0040 {
status = "disabled";
};
+ vpu_reset: vpu-reset@38320000 {
+ compatible = "fsl,imx8mq-vpu-reset", "syscon";
+ reg = <0x38320000 0x10000>;
+ clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+ <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
+ <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+ assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
+ <&clk IMX8MQ_CLK_VPU_G2>,
+ <&clk IMX8MQ_CLK_VPU_BUS>,
+ <&clk IMX8MQ_VPU_PLL_BYPASS>;
+ assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
+ <&clk IMX8MQ_VPU_PLL_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_VPU_PLL>;
+ assigned-clock-rates = <600000000>, <300000000>,
+ <800000000>, <0>;
+ #reset-cells = <1>;
+ };
+
vpu: video-codec@38300000 {
compatible = "nxp,imx8mq-vpu";
reg = <0x38300000 0x10000>,
- <0x38310000 0x10000>,
- <0x38320000 0x10000>;
- reg-names = "g1", "g2", "ctrl";
+ <0x38310000 0x10000>;
+ reg-names = "g1", "g2";
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "g1", "g2";
clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
- <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
- <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
- clock-names = "g1", "g2", "bus";
+ <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+ clock-names = "g1", "g2";
assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
<&clk IMX8MQ_CLK_VPU_G2>,
<&clk IMX8MQ_CLK_VPU_BUS>,
@@ -1290,6 +1308,7 @@ vpu: video-codec@38300000 {
<&clk IMX8MQ_VPU_PLL>;
assigned-clock-rates = <600000000>, <600000000>,
<800000000>, <0>;
+ resets = <&vpu_reset IMX8MQ_RESET_VPU_RESET_G1>;
power-domains = <&pgc_vpu>;
};
--
2.25.1
Le 03/03/2021 à 15:39, Philipp Zabel a écrit :
> On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
>> Rather use a reset like feature inside the driver use the reset
>> controller API to get the same result.
>>
>> Signed-off-by: Benjamin Gaignard <[email protected]>
>> ---
>> drivers/staging/media/hantro/Kconfig | 1 +
>> drivers/staging/media/hantro/imx8m_vpu_hw.c | 61 ++++-----------------
>> 2 files changed, 12 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
>> index 5b6cf9f62b1a..dd1d4dde2658 100644
>> --- a/drivers/staging/media/hantro/Kconfig
>> +++ b/drivers/staging/media/hantro/Kconfig
>> @@ -20,6 +20,7 @@ config VIDEO_HANTRO_IMX8M
>> bool "Hantro VPU i.MX8M support"
>> depends on VIDEO_HANTRO
>> depends on ARCH_MXC || COMPILE_TEST
>> + select RESET_VPU_IMX8MQ
>> default y
>> help
>> Enable support for i.MX8M SoCs.
>> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
>> index c222de075ef4..d5b4312b9391 100644
>> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
>> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
>> @@ -7,49 +7,12 @@
>>
>> #include <linux/clk.h>
>> #include <linux/delay.h>
>> +#include <linux/reset.h>
>>
>> #include "hantro.h"
>> #include "hantro_jpeg.h"
>> #include "hantro_g1_regs.h"
>>
>> -#define CTRL_SOFT_RESET 0x00
>> -#define RESET_G1 BIT(1)
>> -#define RESET_G2 BIT(0)
>> -
>> -#define CTRL_CLOCK_ENABLE 0x04
>> -#define CLOCK_G1 BIT(1)
>> -#define CLOCK_G2 BIT(0)
>> -
>> -#define CTRL_G1_DEC_FUSE 0x08
>> -#define CTRL_G1_PP_FUSE 0x0c
>> -#define CTRL_G2_DEC_FUSE 0x10
>> -
>> -static void imx8m_soft_reset(struct hantro_dev *vpu, u32 reset_bits)
>> -{
>> - u32 val;
>> -
>> - /* Assert */
>> - val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
>> - val &= ~reset_bits;
>> - writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
>> -
>> - udelay(2);
>> -
>> - /* Release */
>> - val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
>> - val |= reset_bits;
>> - writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
>> -}
>> -
>> -static void imx8m_clk_enable(struct hantro_dev *vpu, u32 clock_bits)
>> -{
>> - u32 val;
>> -
>> - val = readl(vpu->ctrl_base + CTRL_CLOCK_ENABLE);
>> - val |= clock_bits;
>> - writel(val, vpu->ctrl_base + CTRL_CLOCK_ENABLE);
> The way it is implemented in the reset driver, the clocks are now
> ungated between assert and deassert instead of afterwards. Is this on
> purpose?
No and that could be changed on next version.
Benjamin
>
> regards
> Philipp
>
Le 03/03/2021 à 15:17, Philipp Zabel a écrit :
> Hi Benjamin,
>
> On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
>> The two VPUs inside IMX8MQ share the same control block which can be see
>> as a reset hardware block.
> This isn't a reset controller though. The control block also contains
> clock gates of some sort and a filter register for the featureset fuses.
> Those shouldn't be manipulated via the reset API.
They are all part of the control block and of the reset process for this
hardware that why I put them here. I guess it is border line :-)
>
>> In order to be able to add the second VPU (for HECV decoding) it will be
>> more handy if the both VPU drivers instance don't have to share the
>> control block registers. This lead to implement it as an independ reset
>> driver and to change the VPU driver to use it.
> Why not switch to a syscon regmap for the control block? That should
> also allow to keep backwards compatibility with the old binding with
> minimal effort.
I will give a try in this direction.
>
>> Please note that this series break the compatibility between the DTB and
>> kernel. This break is limited to IMX8MQ SoC and is done when the driver
>> is still in staging directory.
> I know in this case we are pretty sure there are no users of this
> binding except for a staging driver, but it would still be nice to keep
> support for the deprecated binding, to avoid the requirement of updating
> kernel and DT in lock-step.
If I want to use a syscon (or a reset) the driver must not ioremap the "ctrl"
registers. It means that "ctrl" has to be removed from the driver requested
reg-names (imx8mq_reg_names[]). Doing that break the kernel/DT compatibility.
Somehow syscon and "ctrl" are exclusive.
Benjamin
>
> regards
> Philipp
>
On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
> IMX8MQ SoC got a dedicated hardware block to reset the video processor
> units (G1 and G2).
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> drivers/reset/Kconfig | 8 ++
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-imx8mq-vpu.c | 169 +++++++++++++++++++++++++++++++
> 3 files changed, 178 insertions(+)
> create mode 100644 drivers/reset/reset-imx8mq-vpu.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 71ab75a46491..fa95380b271a 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -80,6 +80,14 @@ config RESET_IMX7
> help
> This enables the reset controller driver for i.MX7 SoCs.
>
> +config RESET_VPU_IMX8MQ
> + tristate "i.MX8MQ VPU Reset Driver"
> + depends on HAS_IOMEM
> + depends on (ARM64 && ARCH_MXC) || COMPILE_TEST
> + select MFD_SYSCON
> + help
> + This enables the VPU reset controller driver for i.MX8MQ SoCs.
> +
> config RESET_INTEL_GW
> bool "Intel Reset Controller Driver"
> depends on OF && HAS_IOMEM
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 1054123fd187..6007e0cdfc05 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
> obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
> obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
> obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
> +obj-$(CONFIG_RESET_VPU_IMX8MQ) += reset-imx8mq-vpu.o
> obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
> obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
> obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> diff --git a/drivers/reset/reset-imx8mq-vpu.c b/drivers/reset/reset-imx8mq-vpu.c
> new file mode 100644
> index 000000000000..14c589f19266
> --- /dev/null
> +++ b/drivers/reset/reset-imx8mq-vpu.c
> @@ -0,0 +1,169 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021, Collabora
> + *
> + * i.MX8MQ VPU Reset Controller driver
> + *
> + * Author: Benjamin Gaignard <[email protected]>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/regmap.h>
> +#include <dt-bindings/reset/imx8mq-vpu-reset.h>
> +
> +#define CTRL_SOFT_RESET 0x00
> +#define RESET_G1 ((u32)BIT(1))
> +#define RESET_G2 ((u32)BIT(0))
> +
> +#define CTRL_ENABLE 0x04
> +#define ENABLE_G1 BIT(1)
> +#define ENABLE_G2 BIT(0)
> +
> +#define CTRL_G1_DEC_FUSE 0x08
> +#define CTRL_G1_PP_FUSE 0x0c
> +#define CTRL_G2_DEC_FUSE 0x10
> +
> +struct imx8mq_vpu_reset {
> + struct reset_controller_dev rcdev;
> + struct regmap *regmap;
> + struct clk_bulk_data *clocks;
> + int num_clocks;
> + struct device *dev;
> +};
> +
> +static inline struct imx8mq_vpu_reset *to_imx8mq_vpu_reset(struct reset_controller_dev *rcdev)
> +{
> + return container_of(rcdev, struct imx8mq_vpu_reset, rcdev);
> +}
> +
> +static int imx8mq_vpu_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + struct imx8mq_vpu_reset *reset = to_imx8mq_vpu_reset(rcdev);
> + int ret = -EINVAL;
> +
> + ret = clk_bulk_prepare_enable(reset->num_clocks, reset->clocks);
> + if (ret) {
> + dev_err(reset->dev, "Failed to prepare clocks\n");
> + return ret;
> + }
> +
> + switch (id) {
> + case IMX8MQ_RESET_VPU_RESET_G1:
> + ret = regmap_update_bits(reset->regmap, CTRL_SOFT_RESET, RESET_G1, ~RESET_G1);
> + ret |= regmap_update_bits(reset->regmap, CTRL_ENABLE, ENABLE_G1, ENABLE_G1);
> + break;
> + case IMX8MQ_RESET_VPU_RESET_G2:
> + ret = regmap_update_bits(reset->regmap, CTRL_SOFT_RESET, RESET_G2, ~RESET_G2);
> + ret |= regmap_update_bits(reset->regmap, CTRL_ENABLE, ENABLE_G2, ENABLE_G2);
This doesn't belong in reset_assert.
> + break;
> + }
> +
> + /* Set values of the fuse registers */
> + ret |= regmap_write(reset->regmap, CTRL_G1_DEC_FUSE, 0xffffffff);
> + ret |= regmap_write(reset->regmap, CTRL_G1_PP_FUSE, 0xffffffff);
> + ret |= regmap_write(reset->regmap, CTRL_G2_DEC_FUSE, 0xffffffff);
Same as above, this doesn't belong in reset_assert.
> + clk_bulk_disable_unprepare(reset->num_clocks, reset->clocks);
Also I assume that only the VPU_DEC_ROOT clock is required to control
these registers. Enabling the VPU_G1_ROOT and VPU_G2_ROOT clocks
(presumably to make sure the resets propagate into the respective VPU
core) would be the reset consumer's responsibility.
regards
Philipp
On Wed, 2021-03-03 at 16:20 +0100, Benjamin Gaignard wrote:
> Le 03/03/2021 à 15:17, Philipp Zabel a écrit :
> > Hi Benjamin,
> >
> > On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
> > > The two VPUs inside IMX8MQ share the same control block which can be see
> > > as a reset hardware block.
> > This isn't a reset controller though. The control block also contains
> > clock gates of some sort and a filter register for the featureset fuses.
> > Those shouldn't be manipulated via the reset API.
>
> They are all part of the control block and of the reset process for this
> hardware that why I put them here. I guess it is border line :-)
I'm pushing back to keep the reset control framework focused on
controlling reset lines. Every side effect (such as the asymmetric clock
ungating) in a random driver makes it harder to reason about behaviour
at the API level, and to review patches for hardware I am not familiar
with.
> > > In order to be able to add the second VPU (for HECV decoding) it will be
> > > more handy if the both VPU drivers instance don't have to share the
> > > control block registers. This lead to implement it as an independ reset
> > > driver and to change the VPU driver to use it.
> > Why not switch to a syscon regmap for the control block? That should
> > also allow to keep backwards compatibility with the old binding with
> > minimal effort.
>
> I will give a try in this direction.
Thank you.
> > > Please note that this series break the compatibility between the DTB and
> > > kernel. This break is limited to IMX8MQ SoC and is done when the driver
> > > is still in staging directory.
> > I know in this case we are pretty sure there are no users of this
> > binding except for a staging driver, but it would still be nice to keep
> > support for the deprecated binding, to avoid the requirement of updating
> > kernel and DT in lock-step.
>
> If I want to use a syscon (or a reset) the driver must not ioremap the "ctrl"
> registers. It means that "ctrl" has to be removed from the driver requested
> reg-names (imx8mq_reg_names[]). Doing that break the kernel/DT compatibility.
> Somehow syscon and "ctrl" are exclusive.
The way the driver is set up currently, yes. You could add a bit of
platform specific probe code, though, that would set up the regmap
either by calling
syscon_regmap_lookup_by_phandle();
for the new binding, or, if the phandle is not available, fall back to
platform_get_resource_byname(..., "ctrl");
devm_ioremap_resource();
devm_regmap_init_mmio();
for the old binding.
The actual codec .reset and variant .runtime_resume ops could be
identical then.
regards
Philipp
Hi Benjamin,
On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
> The two VPUs inside IMX8MQ share the same control block which can be see
> as a reset hardware block.
This isn't a reset controller though. The control block also contains
clock gates of some sort and a filter register for the featureset fuses.
Those shouldn't be manipulated via the reset API.
> In order to be able to add the second VPU (for HECV decoding) it will be
> more handy if the both VPU drivers instance don't have to share the
> control block registers. This lead to implement it as an independ reset
> driver and to change the VPU driver to use it.
Why not switch to a syscon regmap for the control block? That should
also allow to keep backwards compatibility with the old binding with
minimal effort.
> Please note that this series break the compatibility between the DTB and
> kernel. This break is limited to IMX8MQ SoC and is done when the driver
> is still in staging directory.
I know in this case we are pretty sure there are no users of this
binding except for a staging driver, but it would still be nice to keep
support for the deprecated binding, to avoid the requirement of updating
kernel and DT in lock-step.
regards
Philipp
On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
> Rather use a reset like feature inside the driver use the reset
> controller API to get the same result.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> drivers/staging/media/hantro/Kconfig | 1 +
> drivers/staging/media/hantro/imx8m_vpu_hw.c | 61 ++++-----------------
> 2 files changed, 12 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
> index 5b6cf9f62b1a..dd1d4dde2658 100644
> --- a/drivers/staging/media/hantro/Kconfig
> +++ b/drivers/staging/media/hantro/Kconfig
> @@ -20,6 +20,7 @@ config VIDEO_HANTRO_IMX8M
> bool "Hantro VPU i.MX8M support"
> depends on VIDEO_HANTRO
> depends on ARCH_MXC || COMPILE_TEST
> + select RESET_VPU_IMX8MQ
> default y
> help
> Enable support for i.MX8M SoCs.
> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> index c222de075ef4..d5b4312b9391 100644
> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> @@ -7,49 +7,12 @@
>
> #include <linux/clk.h>
> #include <linux/delay.h>
> +#include <linux/reset.h>
>
> #include "hantro.h"
> #include "hantro_jpeg.h"
> #include "hantro_g1_regs.h"
>
> -#define CTRL_SOFT_RESET 0x00
> -#define RESET_G1 BIT(1)
> -#define RESET_G2 BIT(0)
> -
> -#define CTRL_CLOCK_ENABLE 0x04
> -#define CLOCK_G1 BIT(1)
> -#define CLOCK_G2 BIT(0)
> -
> -#define CTRL_G1_DEC_FUSE 0x08
> -#define CTRL_G1_PP_FUSE 0x0c
> -#define CTRL_G2_DEC_FUSE 0x10
> -
> -static void imx8m_soft_reset(struct hantro_dev *vpu, u32 reset_bits)
> -{
> - u32 val;
> -
> - /* Assert */
> - val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
> - val &= ~reset_bits;
> - writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
> -
> - udelay(2);
> -
> - /* Release */
> - val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
> - val |= reset_bits;
> - writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
> -}
> -
> -static void imx8m_clk_enable(struct hantro_dev *vpu, u32 clock_bits)
> -{
> - u32 val;
> -
> - val = readl(vpu->ctrl_base + CTRL_CLOCK_ENABLE);
> - val |= clock_bits;
> - writel(val, vpu->ctrl_base + CTRL_CLOCK_ENABLE);
The way it is implemented in the reset driver, the clocks are now
ungated between assert and deassert instead of afterwards. Is this on
purpose?
regards
Philipp
On Wed, Mar 3, 2021 at 5:24 PM Philipp Zabel <[email protected]> wrote:
>
> On Wed, 2021-03-03 at 16:20 +0100, Benjamin Gaignard wrote:
> > Le 03/03/2021 à 15:17, Philipp Zabel a écrit :
> > > Hi Benjamin,
> > >
> > > On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
> > > > The two VPUs inside IMX8MQ share the same control block which can be see
> > > > as a reset hardware block.
> > > This isn't a reset controller though. The control block also contains
> > > clock gates of some sort and a filter register for the featureset fuses.
> > > Those shouldn't be manipulated via the reset API.
This driver is very similar to several other patches for clk_blk
control [1] which contain both resets and clock-enables on the
i.MX8MP, i.MX8MM and i.MX8MN. In those cases, there are some specific
power domain controls that are needed, but I wonder if the approach to
creating resets and clock enables could be used in a similar way if
the IMX8MQ doesn't have the same quirks. In the case of the i.MX8M
Mini, I think it has the same VPU.
[1] - https://patchwork.kernel.org/project/linux-clk/patch/[email protected]/
adam
> >
> > They are all part of the control block and of the reset process for this
> > hardware that why I put them here. I guess it is border line :-)
>
> I'm pushing back to keep the reset control framework focused on
> controlling reset lines. Every side effect (such as the asymmetric clock
> ungating) in a random driver makes it harder to reason about behaviour
> at the API level, and to review patches for hardware I am not familiar
> with.
>
> > > > In order to be able to add the second VPU (for HECV decoding) it will be
> > > > more handy if the both VPU drivers instance don't have to share the
> > > > control block registers. This lead to implement it as an independ reset
> > > > driver and to change the VPU driver to use it.
> > > Why not switch to a syscon regmap for the control block? That should
> > > also allow to keep backwards compatibility with the old binding with
> > > minimal effort.
> >
> > I will give a try in this direction.
>
> Thank you.
>
> > > > Please note that this series break the compatibility between the DTB and
> > > > kernel. This break is limited to IMX8MQ SoC and is done when the driver
> > > > is still in staging directory.
> > > I know in this case we are pretty sure there are no users of this
> > > binding except for a staging driver, but it would still be nice to keep
> > > support for the deprecated binding, to avoid the requirement of updating
> > > kernel and DT in lock-step.
> >
> > If I want to use a syscon (or a reset) the driver must not ioremap the "ctrl"
> > registers. It means that "ctrl" has to be removed from the driver requested
> > reg-names (imx8mq_reg_names[]). Doing that break the kernel/DT compatibility.
> > Somehow syscon and "ctrl" are exclusive.
>
> The way the driver is set up currently, yes. You could add a bit of
> platform specific probe code, though, that would set up the regmap
> either by calling
> syscon_regmap_lookup_by_phandle();
> for the new binding, or, if the phandle is not available, fall back to
> platform_get_resource_byname(..., "ctrl");
> devm_ioremap_resource();
> devm_regmap_init_mmio();
> for the old binding.
> The actual codec .reset and variant .runtime_resume ops could be
> identical then.
>
> regards
> Philipp
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Le 03/03/2021 à 17:25, Philipp Zabel a écrit :
> On Wed, 2021-03-03 at 16:20 +0100, Benjamin Gaignard wrote:
>> Le 03/03/2021 à 15:17, Philipp Zabel a écrit :
>>> Hi Benjamin,
>>>
>>> On Mon, 2021-03-01 at 16:17 +0100, Benjamin Gaignard wrote:
>>>> The two VPUs inside IMX8MQ share the same control block which can be see
>>>> as a reset hardware block.
>>> This isn't a reset controller though. The control block also contains
>>> clock gates of some sort and a filter register for the featureset fuses.
>>> Those shouldn't be manipulated via the reset API.
>> They are all part of the control block and of the reset process for this
>> hardware that why I put them here. I guess it is border line :-)
> I'm pushing back to keep the reset control framework focused on
> controlling reset lines. Every side effect (such as the asymmetric clock
> ungating) in a random driver makes it harder to reason about behaviour
> at the API level, and to review patches for hardware I am not familiar
> with.
>
>>>> In order to be able to add the second VPU (for HECV decoding) it will be
>>>> more handy if the both VPU drivers instance don't have to share the
>>>> control block registers. This lead to implement it as an independ reset
>>>> driver and to change the VPU driver to use it.
>>> Why not switch to a syscon regmap for the control block? That should
>>> also allow to keep backwards compatibility with the old binding with
>>> minimal effort.
>> I will give a try in this direction.
> Thank you.
>
>>>> Please note that this series break the compatibility between the DTB and
>>>> kernel. This break is limited to IMX8MQ SoC and is done when the driver
>>>> is still in staging directory.
>>> I know in this case we are pretty sure there are no users of this
>>> binding except for a staging driver, but it would still be nice to keep
>>> support for the deprecated binding, to avoid the requirement of updating
>>> kernel and DT in lock-step.
>> If I want to use a syscon (or a reset) the driver must not ioremap the "ctrl"
>> registers. It means that "ctrl" has to be removed from the driver requested
>> reg-names (imx8mq_reg_names[]). Doing that break the kernel/DT compatibility.
>> Somehow syscon and "ctrl" are exclusive.
> The way the driver is set up currently, yes. You could add a bit of
> platform specific probe code, though, that would set up the regmap
> either by calling
> syscon_regmap_lookup_by_phandle();
> for the new binding, or, if the phandle is not available, fall back to
> platform_get_resource_byname(..., "ctrl");
> devm_ioremap_resource();
> devm_regmap_init_mmio();
> for the old binding.
> The actual codec .reset and variant .runtime_resume ops could be
> identical then.
I made it works with syscon and your proposal.
The next version of the patches will be without reset and won't break
DT compatibility.
Thanks for your help,
Benjamin
>
> regards
> Philipp
>
On Mon, Mar 01, 2021 at 04:17:49PM +0100, Benjamin Gaignard wrote:
> The two VPUs inside IMX8MQ share the same control block which can be see
> as a reset hardware block.
> In order to be able to add the second VPU (for HECV decoding) it will be
> more handy if the both VPU drivers instance don't have to share the
> control block registers. This lead to implement it as an independ reset
> driver and to change the VPU driver to use it.
>
> Please note that this series break the compatibility between the DTB and
> kernel. This break is limited to IMX8MQ SoC and is done when the driver
> is still in staging directory.
As this information will be lost, please put in the binding and dts
patch.
>
> version 3:
> - Fix error in VPU example node
>
> version 2:
> - Document the change in VPU bindings
>
> Benjamin Gaignard (5):
> dt-bindings: reset: IMX8MQ VPU reset
> dt-bindings: media: IMX8MQ VPU: document reset usage
> reset: Add reset driver for IMX8MQ VPU block
> media: hantro: Use reset driver
> arm64: dts: imx8mq: Use reset driver for VPU hardware block
>
> .../bindings/media/nxp,imx8mq-vpu.yaml | 14 +-
> .../bindings/reset/fsl,imx8mq-vpu-reset.yaml | 54 ++++++
> arch/arm64/boot/dts/freescale/imx8mq.dtsi | 31 +++-
> drivers/reset/Kconfig | 8 +
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-imx8mq-vpu.c | 169 ++++++++++++++++++
> drivers/staging/media/hantro/Kconfig | 1 +
> drivers/staging/media/hantro/imx8m_vpu_hw.c | 61 ++-----
> include/dt-bindings/reset/imx8mq-vpu-reset.h | 16 ++
> 9 files changed, 294 insertions(+), 61 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
> create mode 100644 drivers/reset/reset-imx8mq-vpu.c
> create mode 100644 include/dt-bindings/reset/imx8mq-vpu-reset.h
>
> --
> 2.25.1
>
On Mon, Mar 01, 2021 at 04:17:50PM +0100, Benjamin Gaignard wrote:
> Document bindings for IMX8MQ VPU reset hardware block
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> .../bindings/reset/fsl,imx8mq-vpu-reset.yaml | 54 +++++++++++++++++++
> include/dt-bindings/reset/imx8mq-vpu-reset.h | 16 ++++++
> 2 files changed, 70 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
> create mode 100644 include/dt-bindings/reset/imx8mq-vpu-reset.h
>
> diff --git a/Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml b/Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
> new file mode 100644
> index 000000000000..00020421c0e3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
> @@ -0,0 +1,54 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/reset/fsl,imx8mq-vpu-reset.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8MQ VPU Reset Controller
> +
> +maintainers:
> + - Benjamin Gaignard <[email protected]>
> +
> +description: |
> + The VPU reset controller is used to reset the video processor
> + unit peripherals. Device nodes that need access to reset lines should
> + specify them as a reset phandle in their corresponding node as
> + specified in reset.txt.
> +
> + For list of all valid reset indices see
> + <dt-bindings/reset/imx8mq-vpu-reset.h> for i.MX8MQ.
> +
> +properties:
> + compatible:
> + items:
> + - const: fsl,imx8mq-vpu-reset
> + - const: syscon
Is there other functionality in the block? If so, add some details in
'description' above.
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + minItems: 1
> + maxItems: 3
Need to say what each clock is.
> +
> + '#reset-cells':
> + const: 1
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - '#reset-cells'
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/imx8mq-clock.h>
> +
> + vpu-reset@38320000 {
reset-controller@...
> + compatible = "fsl,imx8mq-vpu-reset", "syscon";
> + reg = <0x38320000 0x10000>;
> + clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> + #reset-cells = <1>;
> + };
> diff --git a/include/dt-bindings/reset/imx8mq-vpu-reset.h b/include/dt-bindings/reset/imx8mq-vpu-reset.h
> new file mode 100644
> index 000000000000..efcbe18177fe
> --- /dev/null
> +++ b/include/dt-bindings/reset/imx8mq-vpu-reset.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2021, Collabora
> + *
> + * i.MX7 System Reset Controller (SRC) driver
> + *
> + * Author: Benjamin Gaignard <[email protected]>
> + */
> +
> +#ifndef DT_BINDINGS_VPU_RESET_IMX8MQ
> +#define DT_BINDINGS_VPU_RESET_IMX8MQ
> +
> +#define IMX8MQ_RESET_VPU_RESET_G1 0
> +#define IMX8MQ_RESET_VPU_RESET_G2 1
> +
> +#endif
> --
> 2.25.1
>
On Mon, Mar 08, 2021 at 11:22:17AM -0700, Rob Herring wrote:
> On Mon, Mar 01, 2021 at 04:17:49PM +0100, Benjamin Gaignard wrote:
> > The two VPUs inside IMX8MQ share the same control block which can be see
> > as a reset hardware block.
> > In order to be able to add the second VPU (for HECV decoding) it will be
> > more handy if the both VPU drivers instance don't have to share the
> > control block registers. This lead to implement it as an independ reset
> > driver and to change the VPU driver to use it.
> >
> > Please note that this series break the compatibility between the DTB and
> > kernel. This break is limited to IMX8MQ SoC and is done when the driver
> > is still in staging directory.
>
> As this information will be lost, please put in the binding and dts
> patch.
Actually, the adding the VPU reset binding doesn't break compatibility,
so just the dts file changes needs it.
>
> >
> > version 3:
> > - Fix error in VPU example node
> >
> > version 2:
> > - Document the change in VPU bindings
> >
> > Benjamin Gaignard (5):
> > dt-bindings: reset: IMX8MQ VPU reset
> > dt-bindings: media: IMX8MQ VPU: document reset usage
> > reset: Add reset driver for IMX8MQ VPU block
> > media: hantro: Use reset driver
> > arm64: dts: imx8mq: Use reset driver for VPU hardware block
> >
> > .../bindings/media/nxp,imx8mq-vpu.yaml | 14 +-
> > .../bindings/reset/fsl,imx8mq-vpu-reset.yaml | 54 ++++++
> > arch/arm64/boot/dts/freescale/imx8mq.dtsi | 31 +++-
> > drivers/reset/Kconfig | 8 +
> > drivers/reset/Makefile | 1 +
> > drivers/reset/reset-imx8mq-vpu.c | 169 ++++++++++++++++++
> > drivers/staging/media/hantro/Kconfig | 1 +
> > drivers/staging/media/hantro/imx8m_vpu_hw.c | 61 ++-----
> > include/dt-bindings/reset/imx8mq-vpu-reset.h | 16 ++
> > 9 files changed, 294 insertions(+), 61 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx8mq-vpu-reset.yaml
> > create mode 100644 drivers/reset/reset-imx8mq-vpu.c
> > create mode 100644 include/dt-bindings/reset/imx8mq-vpu-reset.h
> >
> > --
> > 2.25.1
> >
On Mon, 01 Mar 2021 16:17:51 +0100, Benjamin Gaignard wrote:
> Document IMX8MQ VPU bindings to add the phandle to the reset driver.
>
> Provide an independent reset driver allow to the both VPUs to share
> their control/reset hardware block. The reset driver replace what
> was previously done be using the 'ctrl' registers inside the driver.
>
> This breaks the compatibility between DTB and kernel but the driver
> is still in staging directory and limited to IMX8MQ SoC.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> version 3:
> - Fix error in VPU example node
>
> .../devicetree/bindings/media/nxp,imx8mq-vpu.yaml | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
Reviewed-by: Rob Herring <[email protected]>