Skip to contentSkip to conversation

media: staging: tegra-vde: Reset memory client

PATCH In review Dmitry Osipenko 2 participants 3 messages May 26, 2018 – May 29, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 media: staging: tegra-vde: Reset memory client

DMA requests must be blocked before resetting VDE HW, otherwise it is possible to get a memory corruption or a machine hang. Use the reset control provided by the Memory Controller to block DMA before resetting the VDE HW.

---

Changelog:

v2:
- Reset HW even if Memory Client resetting fails.

 drivers/staging/media/tegra-vde/tegra-vde.c | 35 +++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)
drivers/staging/media/tegra-vde/tegra-vde.c +33 -2
index 90177a59b97c..6f06061a40d9 100644
@@ -73,6 +73,7 @@ struct tegra_vde {
 	struct mutex lock;
 	struct miscdevice miscdev;
 	struct reset_control *rst;
+	struct reset_control *rst_mc;
 	struct gen_pool *iram_pool;
 	struct completion decode_completion;
 	struct clk *clk;
@@ -850,9 +851,23 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
 	 * We rely on the VDE registers reset value, otherwise VDE
 	 * causes bus lockup.
 	 */
+	ret = reset_control_assert(vde->rst_mc);
+	if (ret) {
+		dev_err(dev, "DEC start: Failed to assert MC reset: %d\n",
+			ret);
+		goto put_runtime_pm;
+	}
+
 	ret = reset_control_reset(vde->rst);
 	if (ret) {
-		dev_err(dev, "Failed to reset HW: %d\n", ret);
+		dev_err(dev, "DEC start: Failed to reset HW: %d\n", ret);
+		goto put_runtime_pm;
+	}
+
+	ret = reset_control_deassert(vde->rst_mc);
+	if (ret) {
+		dev_err(dev, "DEC start: Failed to deassert MC reset: %d\n",
+			ret);
 		goto put_runtime_pm;
 	}
 
@@ -880,9 +895,18 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
 		ret = timeout;
 	}
 
+	/*
+	 * At first reset memory client to avoid resetting VDE HW in the
+	 * middle of DMA which could result into memory corruption or hang
+	 * the whole system.
+	 */
+	err = reset_control_assert(vde->rst_mc);
+	if (err)
+		dev_err(dev, "DEC end: Failed to assert MC reset: %d\n", err);
+
 	err = reset_control_assert(vde->rst);
 	if (err)
-		dev_err(dev, "Failed to assert HW reset: %d\n", err);
+		dev_err(dev, "DEC end: Failed to assert HW reset: %d\n", err);
 
 put_runtime_pm:
 	pm_runtime_mark_last_busy(dev);
@@ -1074,6 +1098,13 @@ static int tegra_vde_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	vde->rst_mc = devm_reset_control_get_optional(dev, "mc");
+	if (IS_ERR(vde->rst_mc)) {
+		err = PTR_ERR(vde->rst_mc);
+		dev_err(dev, "Could not get MC reset %d\n", err);
+		return err;
+	}
+
 	irq = platform_get_irq_byname(pdev, "sync-token");
 	if (irq < 0)
 		return irq;
Signature · 1 line
2.17.0
#1 lore raw

Hi Dmitry,

Quoted 5 lines · Dmitry Osipenko

DMA requests must be blocked before resetting VDE HW, otherwise it is possible to get a memory corruption or a machine hang. Use the reset control provided by the Memory Controller to block DMA before resetting the VDE HW.

Quoted 7 lines

---

Changelog:

v2:
- Reset HW even if Memory Client resetting fails.

Please note that v1 has already been merged, so if you can make a v3 rebased on top of the latest media_tree master branch, then I'll queue that up for 4.18.

Regards,

Hans

Quoted 76 lines
 drivers/staging/media/tegra-vde/tegra-vde.c | 35 +++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)
drivers/staging/media/tegra-vde/tegra-vde.c +33 -2
index 90177a59b97c..6f06061a40d9 100644
@@ -73,6 +73,7 @@ struct tegra_vde {
 	struct mutex lock;
 	struct miscdevice miscdev;
 	struct reset_control *rst;
+	struct reset_control *rst_mc;
 	struct gen_pool *iram_pool;
 	struct completion decode_completion;
 	struct clk *clk;
@@ -850,9 +851,23 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
 	 * We rely on the VDE registers reset value, otherwise VDE
 	 * causes bus lockup.
 	 */
+	ret = reset_control_assert(vde->rst_mc);
+	if (ret) {
+		dev_err(dev, "DEC start: Failed to assert MC reset: %d\n",
+			ret);
+		goto put_runtime_pm;
+	}
+
 	ret = reset_control_reset(vde->rst);
 	if (ret) {
-		dev_err(dev, "Failed to reset HW: %d\n", ret);
+		dev_err(dev, "DEC start: Failed to reset HW: %d\n", ret);
+		goto put_runtime_pm;
+	}
+
+	ret = reset_control_deassert(vde->rst_mc);
+	if (ret) {
+		dev_err(dev, "DEC start: Failed to deassert MC reset: %d\n",
+			ret);
 		goto put_runtime_pm;
 	}
 
@@ -880,9 +895,18 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
 		ret = timeout;
 	}
 
+	/*
+	 * At first reset memory client to avoid resetting VDE HW in the
+	 * middle of DMA which could result into memory corruption or hang
+	 * the whole system.
+	 */
+	err = reset_control_assert(vde->rst_mc);
+	if (err)
+		dev_err(dev, "DEC end: Failed to assert MC reset: %d\n", err);
+
 	err = reset_control_assert(vde->rst);
 	if (err)
-		dev_err(dev, "Failed to assert HW reset: %d\n", err);
+		dev_err(dev, "DEC end: Failed to assert HW reset: %d\n", err);
 
 put_runtime_pm:
 	pm_runtime_mark_last_busy(dev);
@@ -1074,6 +1098,13 @@ static int tegra_vde_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	vde->rst_mc = devm_reset_control_get_optional(dev, "mc");
+	if (IS_ERR(vde->rst_mc)) {
+		err = PTR_ERR(vde->rst_mc);
+		dev_err(dev, "Could not get MC reset %d\n", err);
+		return err;
+	}
+
 	irq = platform_get_irq_byname(pdev, "sync-token");
 	if (irq < 0)
 		return irq;
#2 lore raw
Quoted 11 lines · Hans Verkuil

Hi Dmitry,

Quoted 8 lines · Dmitry Osipenko

DMA requests must be blocked before resetting VDE HW, otherwise it is possible to get a memory corruption or a machine hang. Use the reset control provided by the Memory Controller to block DMA before resetting the VDE HW.

---

Quoted 9 lines
Quoted 4 lines

Changelog:

v2:
- Reset HW even if Memory Client resetting fails.

Please note that v1 has already been merged, so if you can make a v3 rebased on top of the latest media_tree master branch, then I'll queue that up for 4.18.

Thank you very much for letting me know, I'll make v3.

Thierry, wouldn't you mind to queue the relevant devicetree patches for 4.18, or it's too late now? We'll have a full set in 4.18 then.