[PATCH] drm/etnaviv: add optional reset support

LECOINTRE Philippe posted 1 patch 2 weeks, 4 days ago
There is a newer version of this series
drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 29 +++++++++++++++++++++++++++
drivers/gpu/drm/etnaviv/etnaviv_gpu.h |  2 ++
2 files changed, 31 insertions(+)
[PATCH] drm/etnaviv: add optional reset support
Posted by LECOINTRE Philippe 2 weeks, 4 days ago
Add optional reset support which is mentioned in vivante,gc.yaml to
allow the driver to work on SoCs whose reset signal is asserted by default
Avoid enabling the interrupt until everything is ready

Signed-off-by: LECOINTRE Philippe <philippe.lecointre@thalesgroup.com>
Reviewed-by: LENAIN Simon <simon.lenain@thalesgroup.com>
---
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 29 +++++++++++++++++++++++++++
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h |  2 ++
 2 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 7c7f97793ddd..f698fec50343 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2015-2018 Etnaviv Project
+ * Copyright (C) 2024 Thales
  */
 
 #include <linux/clk.h>
@@ -13,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/thermal.h>
 
 #include "etnaviv_cmdbuf.h"
@@ -1629,8 +1631,24 @@ static int etnaviv_gpu_clk_enable(struct etnaviv_gpu *gpu)
 	if (ret)
 		goto disable_clk_core;
 
+	/* 32 core clock cycles (slowest clock) required before deassertion. */
+	/* 1 microsecond might match all implementations */
+	usleep_range(1, 2);
+
+	ret = reset_control_deassert(gpu->rst);
+	if (ret)
+		goto disable_clk_shader;
+
+	/* 128 core clock cycles (slowest clock) required before any activity on AHB. */
+	/* 1 microsecond might match all implementations */
+	usleep_range(1, 2);
+
+	enable_irq(gpu->irq);
+
 	return 0;
 
+disable_clk_shader:
+	clk_disable_unprepare(gpu->clk_shader);
 disable_clk_core:
 	clk_disable_unprepare(gpu->clk_core);
 disable_clk_bus:
@@ -1643,6 +1661,8 @@ static int etnaviv_gpu_clk_enable(struct etnaviv_gpu *gpu)
 
 static int etnaviv_gpu_clk_disable(struct etnaviv_gpu *gpu)
 {
+	disable_irq(gpu->irq);
+	reset_control_assert(gpu->rst);
 	clk_disable_unprepare(gpu->clk_shader);
 	clk_disable_unprepare(gpu->clk_core);
 	clk_disable_unprepare(gpu->clk_bus);
@@ -1876,6 +1896,9 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
 	if (gpu->irq < 0)
 		return gpu->irq;
 
+	/* Avoid enabling the interrupt until everything is ready */
+	irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
+
 	err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0,
 			       dev_name(gpu->dev), gpu);
 	if (err) {
@@ -1883,6 +1906,12 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	/* Get Reset: */
+	gpu->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
+	if (IS_ERR(gpu->rst))
+		return dev_err_probe(dev, PTR_ERR(gpu->rst),
+				     "failed to get reset\n");
+
 	/* Get Clocks: */
 	gpu->clk_reg = devm_clk_get_optional(&pdev->dev, "reg");
 	DBG("clk_reg: %p", gpu->clk_reg);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 31322195b9e4..8c181191755e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2015-2018 Etnaviv Project
+ * Copyright (C) 2024 Thales
  */
 
 #ifndef __ETNAVIV_GPU_H__
@@ -157,6 +158,7 @@ struct etnaviv_gpu {
 	struct clk *clk_reg;
 	struct clk *clk_core;
 	struct clk *clk_shader;
+	struct reset_control *rst;
 
 	unsigned int freq_scale;
 	unsigned int fe_waitcycles;
-- 
2.19.1
Re: [PATCH] drm/etnaviv: add optional reset support
Posted by kernel test robot 2 weeks, 4 days ago
Hi LECOINTRE,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on drm-exynos/exynos-drm-next drm-misc/drm-misc-next linus/master drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip v6.12-rc6]
[cannot apply to next-20241105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/LECOINTRE-Philippe/drm-etnaviv-add-optional-reset-support/20241105-224118
base:   git://anongit.freedesktop.org/drm/drm drm-next
patch link:    https://lore.kernel.org/r/0825fa6ad3954cda970b42c25b45fb0d%40thalesgroup.com
patch subject: [PATCH] drm/etnaviv: add optional reset support
config: i386-buildonly-randconfig-004-20241106 (https://download.01.org/0day-ci/archive/20241106/202411060619.P5NY0vzY-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241106/202411060619.P5NY0vzY-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/202411060619.P5NY0vzY-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/etnaviv/etnaviv_gpu.c:11:
   In file included from include/linux/dma-mapping.h:11:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2213:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/gpu/drm/etnaviv/etnaviv_gpu.c:1900:2: error: call to undeclared function 'irq_set_status_flags'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1900 |         irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
         |         ^
>> drivers/gpu/drm/etnaviv/etnaviv_gpu.c:1900:33: error: use of undeclared identifier 'IRQ_NOAUTOEN'
    1900 |         irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
         |                                        ^
   1 warning and 2 errors generated.


vim +/irq_set_status_flags +1900 drivers/gpu/drm/etnaviv/etnaviv_gpu.c

  1874	
  1875	static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
  1876	{
  1877		struct device *dev = &pdev->dev;
  1878		struct etnaviv_gpu *gpu;
  1879		int err;
  1880	
  1881		gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL);
  1882		if (!gpu)
  1883			return -ENOMEM;
  1884	
  1885		gpu->dev = &pdev->dev;
  1886		mutex_init(&gpu->lock);
  1887		mutex_init(&gpu->sched_lock);
  1888	
  1889		/* Map registers: */
  1890		gpu->mmio = devm_platform_ioremap_resource(pdev, 0);
  1891		if (IS_ERR(gpu->mmio))
  1892			return PTR_ERR(gpu->mmio);
  1893	
  1894		/* Get Interrupt: */
  1895		gpu->irq = platform_get_irq(pdev, 0);
  1896		if (gpu->irq < 0)
  1897			return gpu->irq;
  1898	
  1899		/* Avoid enabling the interrupt until everything is ready */
> 1900		irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
  1901	
  1902		err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0,
  1903				       dev_name(gpu->dev), gpu);
  1904		if (err) {
  1905			dev_err(dev, "failed to request IRQ%u: %d\n", gpu->irq, err);
  1906			return err;
  1907		}
  1908	
  1909		/* Get Reset: */
  1910		gpu->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
  1911		if (IS_ERR(gpu->rst))
  1912			return dev_err_probe(dev, PTR_ERR(gpu->rst),
  1913					     "failed to get reset\n");
  1914	
  1915		/* Get Clocks: */
  1916		gpu->clk_reg = devm_clk_get_optional(&pdev->dev, "reg");
  1917		DBG("clk_reg: %p", gpu->clk_reg);
  1918		if (IS_ERR(gpu->clk_reg))
  1919			return PTR_ERR(gpu->clk_reg);
  1920	
  1921		gpu->clk_bus = devm_clk_get_optional(&pdev->dev, "bus");
  1922		DBG("clk_bus: %p", gpu->clk_bus);
  1923		if (IS_ERR(gpu->clk_bus))
  1924			return PTR_ERR(gpu->clk_bus);
  1925	
  1926		gpu->clk_core = devm_clk_get(&pdev->dev, "core");
  1927		DBG("clk_core: %p", gpu->clk_core);
  1928		if (IS_ERR(gpu->clk_core))
  1929			return PTR_ERR(gpu->clk_core);
  1930		gpu->base_rate_core = clk_get_rate(gpu->clk_core);
  1931	
  1932		gpu->clk_shader = devm_clk_get_optional(&pdev->dev, "shader");
  1933		DBG("clk_shader: %p", gpu->clk_shader);
  1934		if (IS_ERR(gpu->clk_shader))
  1935			return PTR_ERR(gpu->clk_shader);
  1936		gpu->base_rate_shader = clk_get_rate(gpu->clk_shader);
  1937	
  1938		/* TODO: figure out max mapped size */
  1939		dev_set_drvdata(dev, gpu);
  1940	
  1941		/*
  1942		 * We treat the device as initially suspended.  The runtime PM
  1943		 * autosuspend delay is rather arbitary: no measurements have
  1944		 * yet been performed to determine an appropriate value.
  1945		 */
  1946		pm_runtime_use_autosuspend(gpu->dev);
  1947		pm_runtime_set_autosuspend_delay(gpu->dev, 200);
  1948		pm_runtime_enable(gpu->dev);
  1949	
  1950		err = component_add(&pdev->dev, &gpu_ops);
  1951		if (err < 0) {
  1952			dev_err(&pdev->dev, "failed to register component: %d\n", err);
  1953			return err;
  1954		}
  1955	
  1956		return 0;
  1957	}
  1958	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] drm/etnaviv: add optional reset support
Posted by kernel test robot 2 weeks, 4 days ago
Hi LECOINTRE,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on drm-exynos/exynos-drm-next drm-misc/drm-misc-next linus/master drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip v6.12-rc6]
[cannot apply to next-20241105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/LECOINTRE-Philippe/drm-etnaviv-add-optional-reset-support/20241105-224118
base:   git://anongit.freedesktop.org/drm/drm drm-next
patch link:    https://lore.kernel.org/r/0825fa6ad3954cda970b42c25b45fb0d%40thalesgroup.com
patch subject: [PATCH] drm/etnaviv: add optional reset support
config: i386-buildonly-randconfig-003-20241106 (https://download.01.org/0day-ci/archive/20241106/202411060610.iIIdHXHP-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241106/202411060610.iIIdHXHP-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/202411060610.iIIdHXHP-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/gpu/drm/etnaviv/etnaviv_gpu.c: In function 'etnaviv_gpu_platform_probe':
>> drivers/gpu/drm/etnaviv/etnaviv_gpu.c:1900:9: error: implicit declaration of function 'irq_set_status_flags' [-Werror=implicit-function-declaration]
    1900 |         irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
         |         ^~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/etnaviv/etnaviv_gpu.c:1900:40: error: 'IRQ_NOAUTOEN' undeclared (first use in this function); did you mean 'IRQF_NO_AUTOEN'?
    1900 |         irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
         |                                        ^~~~~~~~~~~~
         |                                        IRQF_NO_AUTOEN
   drivers/gpu/drm/etnaviv/etnaviv_gpu.c:1900:40: note: each undeclared identifier is reported only once for each function it appears in
   cc1: all warnings being treated as errors


vim +/irq_set_status_flags +1900 drivers/gpu/drm/etnaviv/etnaviv_gpu.c

  1874	
  1875	static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
  1876	{
  1877		struct device *dev = &pdev->dev;
  1878		struct etnaviv_gpu *gpu;
  1879		int err;
  1880	
  1881		gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL);
  1882		if (!gpu)
  1883			return -ENOMEM;
  1884	
  1885		gpu->dev = &pdev->dev;
  1886		mutex_init(&gpu->lock);
  1887		mutex_init(&gpu->sched_lock);
  1888	
  1889		/* Map registers: */
  1890		gpu->mmio = devm_platform_ioremap_resource(pdev, 0);
  1891		if (IS_ERR(gpu->mmio))
  1892			return PTR_ERR(gpu->mmio);
  1893	
  1894		/* Get Interrupt: */
  1895		gpu->irq = platform_get_irq(pdev, 0);
  1896		if (gpu->irq < 0)
  1897			return gpu->irq;
  1898	
  1899		/* Avoid enabling the interrupt until everything is ready */
> 1900		irq_set_status_flags(gpu->irq, IRQ_NOAUTOEN);
  1901	
  1902		err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0,
  1903				       dev_name(gpu->dev), gpu);
  1904		if (err) {
  1905			dev_err(dev, "failed to request IRQ%u: %d\n", gpu->irq, err);
  1906			return err;
  1907		}
  1908	
  1909		/* Get Reset: */
  1910		gpu->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
  1911		if (IS_ERR(gpu->rst))
  1912			return dev_err_probe(dev, PTR_ERR(gpu->rst),
  1913					     "failed to get reset\n");
  1914	
  1915		/* Get Clocks: */
  1916		gpu->clk_reg = devm_clk_get_optional(&pdev->dev, "reg");
  1917		DBG("clk_reg: %p", gpu->clk_reg);
  1918		if (IS_ERR(gpu->clk_reg))
  1919			return PTR_ERR(gpu->clk_reg);
  1920	
  1921		gpu->clk_bus = devm_clk_get_optional(&pdev->dev, "bus");
  1922		DBG("clk_bus: %p", gpu->clk_bus);
  1923		if (IS_ERR(gpu->clk_bus))
  1924			return PTR_ERR(gpu->clk_bus);
  1925	
  1926		gpu->clk_core = devm_clk_get(&pdev->dev, "core");
  1927		DBG("clk_core: %p", gpu->clk_core);
  1928		if (IS_ERR(gpu->clk_core))
  1929			return PTR_ERR(gpu->clk_core);
  1930		gpu->base_rate_core = clk_get_rate(gpu->clk_core);
  1931	
  1932		gpu->clk_shader = devm_clk_get_optional(&pdev->dev, "shader");
  1933		DBG("clk_shader: %p", gpu->clk_shader);
  1934		if (IS_ERR(gpu->clk_shader))
  1935			return PTR_ERR(gpu->clk_shader);
  1936		gpu->base_rate_shader = clk_get_rate(gpu->clk_shader);
  1937	
  1938		/* TODO: figure out max mapped size */
  1939		dev_set_drvdata(dev, gpu);
  1940	
  1941		/*
  1942		 * We treat the device as initially suspended.  The runtime PM
  1943		 * autosuspend delay is rather arbitary: no measurements have
  1944		 * yet been performed to determine an appropriate value.
  1945		 */
  1946		pm_runtime_use_autosuspend(gpu->dev);
  1947		pm_runtime_set_autosuspend_delay(gpu->dev, 200);
  1948		pm_runtime_enable(gpu->dev);
  1949	
  1950		err = component_add(&pdev->dev, &gpu_ops);
  1951		if (err < 0) {
  1952			dev_err(&pdev->dev, "failed to register component: %d\n", err);
  1953			return err;
  1954		}
  1955	
  1956		return 0;
  1957	}
  1958	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki