[v2,5/5] drm/msm/a6xx: Use genpd notifier to ensure cx-gdsc collapse

Message ID 20221216155038.v2.5.I9e10545c6a448d5eb1b734839b871d1b3146dac3@changeid
State New
Headers
Series Improve GPU reset sequence for Adreno GPU |

Commit Message

Akhil P Oommen Dec. 16, 2022, 10:21 a.m. UTC
  As per the recommended recovery sequence of adreno gpu, cx gdsc should
collapse at hardware before it is turned back ON. This helps to clear
out the stale states in hardware before it is reinitialized. Use the
genpd notifier along with the newly introduced
dev_pm_genpd_synced_poweroff() api to ensure that cx gdsc has collapsed
before we turn it back ON.

Signed-off-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
---

Changes in v2:
- Select PM_GENERIC_DOMAINS from Kconfig

 drivers/gpu/drm/msm/Kconfig           |  1 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 15 +++++++++++++++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  6 ++++++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +++++++++++
 4 files changed, 33 insertions(+)
  

Comments

kernel test robot Dec. 16, 2022, 1:50 p.m. UTC | #1
Hi Akhil,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on next-20221216]
[also build test ERROR on linus/master]
[cannot apply to drm-misc/drm-misc-next rafael-pm/linux-next clk/clk-next v6.1 v6.1-rc8 v6.1-rc7 v6.1]
[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/Akhil-P-Oommen/Improve-GPU-reset-sequence-for-Adreno-GPU/20221216-182442
patch link:    https://lore.kernel.org/r/20221216155038.v2.5.I9e10545c6a448d5eb1b734839b871d1b3146dac3%40changeid
patch subject: [PATCH v2 5/5] drm/msm/a6xx: Use genpd notifier to ensure cx-gdsc collapse
config: riscv-randconfig-r036-20221216
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 98b13979fb05f3ed288a900deb843e7b27589e58)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/463ea4db689a5294e32d9251736512507781b51c
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Akhil-P-Oommen/Improve-GPU-reset-sequence-for-Adreno-GPU/20221216-182442
        git checkout 463ea4db689a5294e32d9251736512507781b51c
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/base/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/base/power/domain.c:654:13: error: use of undeclared identifier 'pm_wq'
           queue_work(pm_wq, &genpd->power_off_work);
                      ^
>> drivers/base/power/domain.c:853:26: error: no member named 'ignore_children' in 'struct dev_pm_info'
                   if (!dev || dev->power.ignore_children)
                               ~~~~~~~~~~ ^
>> drivers/base/power/domain.c:3090:17: error: no member named 'runtime_error' in 'struct dev_pm_info'
           if (dev->power.runtime_error)
               ~~~~~~~~~~ ^
>> drivers/base/power/domain.c:3092:22: error: no member named 'disable_depth' in 'struct dev_pm_info'
           else if (dev->power.disable_depth)
                    ~~~~~~~~~~ ^
>> drivers/base/power/domain.c:3094:22: error: no member named 'runtime_status' in 'struct dev_pm_info'
           else if (dev->power.runtime_status < ARRAY_SIZE(status_lookup))
                    ~~~~~~~~~~ ^
   drivers/base/power/domain.c:3095:32: error: no member named 'runtime_status' in 'struct dev_pm_info'
                   p = status_lookup[dev->power.runtime_status];
                                     ~~~~~~~~~~ ^
   6 errors generated.
--
>> drivers/base/power/domain_governor.c:85:18: error: no member named 'ignore_children' in 'struct dev_pm_info'
           if (!dev->power.ignore_children)
                ~~~~~~~~~~ ^
   1 error generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for PM_GENERIC_DOMAINS
   Depends on [n]: PM [=n]
   Selected by [m]:
   - DRM_MSM [=m] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=m] || QCOM_LLCC [=m]=n) && (QCOM_COMMAND_DB [=m] || QCOM_COMMAND_DB [=m]=n)


vim +/pm_wq +654 drivers/base/power/domain.c

c8f0ea45169c57 Geert Uytterhoeven 2014-11-10  644  
29e47e2173349e Ulf Hansson        2015-09-02  645  /**
86e12eac1f7f84 Ulf Hansson        2016-12-08  646   * genpd_queue_power_off_work - Queue up the execution of genpd_power_off().
a3d09c73492e57 Moritz Fischer     2016-01-27  647   * @genpd: PM domain to power off.
29e47e2173349e Ulf Hansson        2015-09-02  648   *
86e12eac1f7f84 Ulf Hansson        2016-12-08  649   * Queue up the execution of genpd_power_off() unless it's already been done
29e47e2173349e Ulf Hansson        2015-09-02  650   * before.
29e47e2173349e Ulf Hansson        2015-09-02  651   */
29e47e2173349e Ulf Hansson        2015-09-02  652  static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
29e47e2173349e Ulf Hansson        2015-09-02  653  {
29e47e2173349e Ulf Hansson        2015-09-02 @654  	queue_work(pm_wq, &genpd->power_off_work);
29e47e2173349e Ulf Hansson        2015-09-02  655  }
29e47e2173349e Ulf Hansson        2015-09-02  656  
1f8728b7adc4c2 Ulf Hansson        2017-02-17  657  /**
1f8728b7adc4c2 Ulf Hansson        2017-02-17  658   * genpd_power_off - Remove power from a given PM domain.
1f8728b7adc4c2 Ulf Hansson        2017-02-17  659   * @genpd: PM domain to power down.
3c64649d1cf9f3 Ulf Hansson        2017-02-17  660   * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the
3c64649d1cf9f3 Ulf Hansson        2017-02-17  661   * RPM status of the releated device is in an intermediate state, not yet turned
3c64649d1cf9f3 Ulf Hansson        2017-02-17  662   * into RPM_SUSPENDED. This means genpd_power_off() must allow one device to not
3c64649d1cf9f3 Ulf Hansson        2017-02-17  663   * be RPM_SUSPENDED, while it tries to power off the PM domain.
763663c9715f5f Yang Yingliang     2021-05-12  664   * @depth: nesting count for lockdep.
1f8728b7adc4c2 Ulf Hansson        2017-02-17  665   *
1f8728b7adc4c2 Ulf Hansson        2017-02-17  666   * If all of the @genpd's devices have been suspended and all of its subdomains
1f8728b7adc4c2 Ulf Hansson        2017-02-17  667   * have been powered down, remove power from @genpd.
1f8728b7adc4c2 Ulf Hansson        2017-02-17  668   */
2da835452a0875 Ulf Hansson        2017-02-17  669  static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
2da835452a0875 Ulf Hansson        2017-02-17  670  			   unsigned int depth)
1f8728b7adc4c2 Ulf Hansson        2017-02-17  671  {
1f8728b7adc4c2 Ulf Hansson        2017-02-17  672  	struct pm_domain_data *pdd;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  673  	struct gpd_link *link;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  674  	unsigned int not_suspended = 0;
f63816e43d9044 Ulf Hansson        2020-09-24  675  	int ret;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  676  
1f8728b7adc4c2 Ulf Hansson        2017-02-17  677  	/*
1f8728b7adc4c2 Ulf Hansson        2017-02-17  678  	 * Do not try to power off the domain in the following situations:
1f8728b7adc4c2 Ulf Hansson        2017-02-17  679  	 * (1) The domain is already in the "power off" state.
1f8728b7adc4c2 Ulf Hansson        2017-02-17  680  	 * (2) System suspend is in progress.
1f8728b7adc4c2 Ulf Hansson        2017-02-17  681  	 */
41e2c8e0060db2 Ulf Hansson        2017-03-20  682  	if (!genpd_status_on(genpd) || genpd->prepared_count > 0)
1f8728b7adc4c2 Ulf Hansson        2017-02-17  683  		return 0;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  684  
ffaa42e8a40b7f Ulf Hansson        2017-03-20  685  	/*
ffaa42e8a40b7f Ulf Hansson        2017-03-20  686  	 * Abort power off for the PM domain in the following situations:
ffaa42e8a40b7f Ulf Hansson        2017-03-20  687  	 * (1) The domain is configured as always on.
ffaa42e8a40b7f Ulf Hansson        2017-03-20  688  	 * (2) When the domain has a subdomain being powered on.
ffaa42e8a40b7f Ulf Hansson        2017-03-20  689  	 */
ed61e18a4b4e44 Leonard Crestez    2019-04-30  690  	if (genpd_is_always_on(genpd) ||
ed61e18a4b4e44 Leonard Crestez    2019-04-30  691  			genpd_is_rpm_always_on(genpd) ||
ed61e18a4b4e44 Leonard Crestez    2019-04-30  692  			atomic_read(&genpd->sd_count) > 0)
1f8728b7adc4c2 Ulf Hansson        2017-02-17  693  		return -EBUSY;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  694  
e7d90cfac5510f Ulf Hansson        2022-02-17  695  	/*
e7d90cfac5510f Ulf Hansson        2022-02-17  696  	 * The children must be in their deepest (powered-off) states to allow
e7d90cfac5510f Ulf Hansson        2022-02-17  697  	 * the parent to be powered off. Note that, there's no need for
e7d90cfac5510f Ulf Hansson        2022-02-17  698  	 * additional locking, as powering on a child, requires the parent's
e7d90cfac5510f Ulf Hansson        2022-02-17  699  	 * lock to be acquired first.
e7d90cfac5510f Ulf Hansson        2022-02-17  700  	 */
e7d90cfac5510f Ulf Hansson        2022-02-17  701  	list_for_each_entry(link, &genpd->parent_links, parent_node) {
e7d90cfac5510f Ulf Hansson        2022-02-17  702  		struct generic_pm_domain *child = link->child;
e7d90cfac5510f Ulf Hansson        2022-02-17  703  		if (child->state_idx < child->state_count - 1)
e7d90cfac5510f Ulf Hansson        2022-02-17  704  			return -EBUSY;
e7d90cfac5510f Ulf Hansson        2022-02-17  705  	}
e7d90cfac5510f Ulf Hansson        2022-02-17  706  
1f8728b7adc4c2 Ulf Hansson        2017-02-17  707  	list_for_each_entry(pdd, &genpd->dev_list, list_node) {
1f8728b7adc4c2 Ulf Hansson        2017-02-17  708  		/*
1f8728b7adc4c2 Ulf Hansson        2017-02-17  709  		 * Do not allow PM domain to be powered off, when an IRQ safe
1f8728b7adc4c2 Ulf Hansson        2017-02-17  710  		 * device is part of a non-IRQ safe domain.
1f8728b7adc4c2 Ulf Hansson        2017-02-17  711  		 */
1f8728b7adc4c2 Ulf Hansson        2017-02-17  712  		if (!pm_runtime_suspended(pdd->dev) ||
7a02444b8fc25a Ulf Hansson        2022-05-11  713  			irq_safe_dev_in_sleep_domain(pdd->dev, genpd))
1f8728b7adc4c2 Ulf Hansson        2017-02-17  714  			not_suspended++;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  715  	}
1f8728b7adc4c2 Ulf Hansson        2017-02-17  716  
3c64649d1cf9f3 Ulf Hansson        2017-02-17  717  	if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on))
1f8728b7adc4c2 Ulf Hansson        2017-02-17  718  		return -EBUSY;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  719  
1f8728b7adc4c2 Ulf Hansson        2017-02-17  720  	if (genpd->gov && genpd->gov->power_down_ok) {
1f8728b7adc4c2 Ulf Hansson        2017-02-17  721  		if (!genpd->gov->power_down_ok(&genpd->domain))
1f8728b7adc4c2 Ulf Hansson        2017-02-17  722  			return -EAGAIN;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  723  	}
1f8728b7adc4c2 Ulf Hansson        2017-02-17  724  
2c9b7f8772033c Ulf Hansson        2018-10-03  725  	/* Default to shallowest state. */
2c9b7f8772033c Ulf Hansson        2018-10-03  726  	if (!genpd->gov)
2c9b7f8772033c Ulf Hansson        2018-10-03  727  		genpd->state_idx = 0;
2c9b7f8772033c Ulf Hansson        2018-10-03  728  
f63816e43d9044 Ulf Hansson        2020-09-24  729  	/* Don't power off, if a child domain is waiting to power on. */
1f8728b7adc4c2 Ulf Hansson        2017-02-17  730  	if (atomic_read(&genpd->sd_count) > 0)
1f8728b7adc4c2 Ulf Hansson        2017-02-17  731  		return -EBUSY;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  732  
1f8728b7adc4c2 Ulf Hansson        2017-02-17  733  	ret = _genpd_power_off(genpd, true);
c6a113b52302ad Lina Iyer          2020-10-15  734  	if (ret) {
c6a113b52302ad Lina Iyer          2020-10-15  735  		genpd->states[genpd->state_idx].rejected++;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  736  		return ret;
c6a113b52302ad Lina Iyer          2020-10-15  737  	}
1f8728b7adc4c2 Ulf Hansson        2017-02-17  738  
49f618e1b669ef Ulf Hansson        2020-09-24  739  	genpd->status = GENPD_STATE_OFF;
afece3ab9a3640 Thara Gopinath     2017-07-14  740  	genpd_update_accounting(genpd);
c6a113b52302ad Lina Iyer          2020-10-15  741  	genpd->states[genpd->state_idx].usage++;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  742  
8d87ae48ced2df Kees Cook          2020-07-08  743  	list_for_each_entry(link, &genpd->child_links, child_node) {
8d87ae48ced2df Kees Cook          2020-07-08  744  		genpd_sd_counter_dec(link->parent);
8d87ae48ced2df Kees Cook          2020-07-08  745  		genpd_lock_nested(link->parent, depth + 1);
8d87ae48ced2df Kees Cook          2020-07-08  746  		genpd_power_off(link->parent, false, depth + 1);
8d87ae48ced2df Kees Cook          2020-07-08  747  		genpd_unlock(link->parent);
1f8728b7adc4c2 Ulf Hansson        2017-02-17  748  	}
1f8728b7adc4c2 Ulf Hansson        2017-02-17  749  
1f8728b7adc4c2 Ulf Hansson        2017-02-17  750  	return 0;
1f8728b7adc4c2 Ulf Hansson        2017-02-17  751  }
1f8728b7adc4c2 Ulf Hansson        2017-02-17  752  
5248051b9afb66 Rafael J. Wysocki  2011-07-01  753  /**
8d87ae48ced2df Kees Cook          2020-07-08  754   * genpd_power_on - Restore power to a given PM domain and its parents.
5248051b9afb66 Rafael J. Wysocki  2011-07-01  755   * @genpd: PM domain to power up.
0106ef5146f9e8 Marek Szyprowski   2016-01-20  756   * @depth: nesting count for lockdep.
5248051b9afb66 Rafael J. Wysocki  2011-07-01  757   *
8d87ae48ced2df Kees Cook          2020-07-08  758   * Restore power to @genpd and all of its parents so that it is possible to
5248051b9afb66 Rafael J. Wysocki  2011-07-01  759   * resume a device belonging to it.
5248051b9afb66 Rafael J. Wysocki  2011-07-01  760   */
86e12eac1f7f84 Ulf Hansson        2016-12-08  761  static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
5248051b9afb66 Rafael J. Wysocki  2011-07-01  762  {
5063ce1571b738 Rafael J. Wysocki  2011-08-08  763  	struct gpd_link *link;
5248051b9afb66 Rafael J. Wysocki  2011-07-01  764  	int ret = 0;
5248051b9afb66 Rafael J. Wysocki  2011-07-01  765  
41e2c8e0060db2 Ulf Hansson        2017-03-20  766  	if (genpd_status_on(genpd))
3f241775c30365 Rafael J. Wysocki  2011-08-08  767  		return 0;
5248051b9afb66 Rafael J. Wysocki  2011-07-01  768  
5063ce1571b738 Rafael J. Wysocki  2011-08-08  769  	/*
5063ce1571b738 Rafael J. Wysocki  2011-08-08  770  	 * The list is guaranteed not to change while the loop below is being
8d87ae48ced2df Kees Cook          2020-07-08  771  	 * executed, unless one of the parents' .power_on() callbacks fiddles
5063ce1571b738 Rafael J. Wysocki  2011-08-08  772  	 * with it.
5063ce1571b738 Rafael J. Wysocki  2011-08-08  773  	 */
8d87ae48ced2df Kees Cook          2020-07-08  774  	list_for_each_entry(link, &genpd->child_links, child_node) {
8d87ae48ced2df Kees Cook          2020-07-08  775  		struct generic_pm_domain *parent = link->parent;
0106ef5146f9e8 Marek Szyprowski   2016-01-20  776  
8d87ae48ced2df Kees Cook          2020-07-08  777  		genpd_sd_counter_inc(parent);
0106ef5146f9e8 Marek Szyprowski   2016-01-20  778  
8d87ae48ced2df Kees Cook          2020-07-08  779  		genpd_lock_nested(parent, depth + 1);
8d87ae48ced2df Kees Cook          2020-07-08  780  		ret = genpd_power_on(parent, depth + 1);
8d87ae48ced2df Kees Cook          2020-07-08  781  		genpd_unlock(parent);
5248051b9afb66 Rafael J. Wysocki  2011-07-01  782  
5063ce1571b738 Rafael J. Wysocki  2011-08-08  783  		if (ret) {
8d87ae48ced2df Kees Cook          2020-07-08  784  			genpd_sd_counter_dec(parent);
9e08cf42969709 Rafael J. Wysocki  2011-08-08  785  			goto err;
5248051b9afb66 Rafael J. Wysocki  2011-07-01  786  		}
5063ce1571b738 Rafael J. Wysocki  2011-08-08  787  	}
5248051b9afb66 Rafael J. Wysocki  2011-07-01  788  
86e12eac1f7f84 Ulf Hansson        2016-12-08  789  	ret = _genpd_power_on(genpd, true);
9e08cf42969709 Rafael J. Wysocki  2011-08-08  790  	if (ret)
9e08cf42969709 Rafael J. Wysocki  2011-08-08  791  		goto err;
0140d8bd47f798 Rafael J. Wysocki  2011-12-01  792  
49f618e1b669ef Ulf Hansson        2020-09-24  793  	genpd->status = GENPD_STATE_ON;
afece3ab9a3640 Thara Gopinath     2017-07-14  794  	genpd_update_accounting(genpd);
afece3ab9a3640 Thara Gopinath     2017-07-14  795  
3f241775c30365 Rafael J. Wysocki  2011-08-08  796  	return 0;
9e08cf42969709 Rafael J. Wysocki  2011-08-08  797  
9e08cf42969709 Rafael J. Wysocki  2011-08-08  798   err:
29e47e2173349e Ulf Hansson        2015-09-02  799  	list_for_each_entry_continue_reverse(link,
8d87ae48ced2df Kees Cook          2020-07-08  800  					&genpd->child_links,
8d87ae48ced2df Kees Cook          2020-07-08  801  					child_node) {
8d87ae48ced2df Kees Cook          2020-07-08  802  		genpd_sd_counter_dec(link->parent);
8d87ae48ced2df Kees Cook          2020-07-08  803  		genpd_lock_nested(link->parent, depth + 1);
8d87ae48ced2df Kees Cook          2020-07-08  804  		genpd_power_off(link->parent, false, depth + 1);
8d87ae48ced2df Kees Cook          2020-07-08  805  		genpd_unlock(link->parent);
29e47e2173349e Ulf Hansson        2015-09-02  806  	}
9e08cf42969709 Rafael J. Wysocki  2011-08-08  807  
3f241775c30365 Rafael J. Wysocki  2011-08-08  808  	return ret;
3f241775c30365 Rafael J. Wysocki  2011-08-08  809  }
3f241775c30365 Rafael J. Wysocki  2011-08-08  810  
ea71c59669f17d Ulf Hansson        2019-10-16  811  static int genpd_dev_pm_start(struct device *dev)
ea71c59669f17d Ulf Hansson        2019-10-16  812  {
ea71c59669f17d Ulf Hansson        2019-10-16  813  	struct generic_pm_domain *genpd = dev_to_genpd(dev);
ea71c59669f17d Ulf Hansson        2019-10-16  814  
ea71c59669f17d Ulf Hansson        2019-10-16  815  	return genpd_start_dev(genpd, dev);
ea71c59669f17d Ulf Hansson        2019-10-16  816  }
ea71c59669f17d Ulf Hansson        2019-10-16  817  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  818  static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  819  				     unsigned long val, void *ptr)
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  820  {
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  821  	struct generic_pm_domain_data *gpd_data;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  822  	struct device *dev;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  823  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  824  	gpd_data = container_of(nb, struct generic_pm_domain_data, nb);
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  825  	dev = gpd_data->base.dev;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  826  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  827  	for (;;) {
f38d1a6d002526 Ulf Hansson        2022-05-11  828  		struct generic_pm_domain *genpd = ERR_PTR(-ENODATA);
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  829  		struct pm_domain_data *pdd;
66d29d802ef3bf Ulf Hansson        2022-05-11  830  		struct gpd_timing_data *td;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  831  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  832  		spin_lock_irq(&dev->power.lock);
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  833  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  834  		pdd = dev->power.subsys_data ?
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  835  				dev->power.subsys_data->domain_data : NULL;
b4883ca449473e Viresh Kumar       2017-05-16  836  		if (pdd) {
66d29d802ef3bf Ulf Hansson        2022-05-11  837  			td = to_gpd_data(pdd)->td;
f38d1a6d002526 Ulf Hansson        2022-05-11  838  			if (td) {
66d29d802ef3bf Ulf Hansson        2022-05-11  839  				td->constraint_changed = true;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  840  				genpd = dev_to_genpd(dev);
f38d1a6d002526 Ulf Hansson        2022-05-11  841  			}
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  842  		}
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  843  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  844  		spin_unlock_irq(&dev->power.lock);
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  845  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  846  		if (!IS_ERR(genpd)) {
35241d12f750d2 Lina Iyer          2016-10-14  847  			genpd_lock(genpd);
f38d1a6d002526 Ulf Hansson        2022-05-11  848  			genpd->gd->max_off_time_changed = true;
35241d12f750d2 Lina Iyer          2016-10-14  849  			genpd_unlock(genpd);
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  850  		}
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  851  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  852  		dev = dev->parent;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01 @853  		if (!dev || dev->power.ignore_children)
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  854  			break;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  855  	}
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  856  
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  857  	return NOTIFY_DONE;
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  858  }
6ff7bb0d02f829 Rafael J. Wysocki  2012-05-01  859
  

Patch

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 3c9dfdb0b328..74f5916f5ca5 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -28,6 +28,7 @@  config DRM_MSM
 	select SYNC_FILE
 	select PM_OPP
 	select NVMEM
+	select PM_GENERIC_DOMAINS
 	help
 	  DRM/KMS driver for MSM/snapdragon.
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 1580d0090f35..c03830957c26 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -1507,6 +1507,17 @@  void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
 	gmu->initialized = false;
 }
 
+static int cxpd_notifier_cb(struct notifier_block *nb,
+			unsigned long action, void *data)
+{
+	struct a6xx_gmu *gmu = container_of(nb, struct a6xx_gmu, pd_nb);
+
+	if (action == GENPD_NOTIFY_OFF)
+		complete_all(&gmu->pd_gate);
+
+	return 0;
+}
+
 int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 {
 	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
@@ -1640,6 +1651,10 @@  int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 		goto detach_cxpd;
 	}
 
+	init_completion(&gmu->pd_gate);
+	complete_all(&gmu->pd_gate);
+	gmu->pd_nb.notifier_call = cxpd_notifier_cb;
+
 	/*
 	 * Get a link to the GX power domain to reset the GPU in case of GMU
 	 * crash
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 5a42dd4dd31f..0bc3eb443fec 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -4,8 +4,10 @@ 
 #ifndef _A6XX_GMU_H_
 #define _A6XX_GMU_H_
 
+#include <linux/completion.h>
 #include <linux/iopoll.h>
 #include <linux/interrupt.h>
+#include <linux/notifier.h>
 #include "msm_drv.h"
 #include "a6xx_hfi.h"
 
@@ -90,6 +92,10 @@  struct a6xx_gmu {
 	bool initialized;
 	bool hung;
 	bool legacy; /* a618 or a630 */
+
+	/* For power domain callback */
+	struct notifier_block pd_nb;
+	struct completion pd_gate;
 };
 
 static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 4b16e75dfa50..dd618b099110 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -10,6 +10,7 @@ 
 
 #include <linux/bitfield.h>
 #include <linux/devfreq.h>
+#include <linux/pm_domain.h>
 #include <linux/soc/qcom/llcc-qcom.h>
 
 #define GPU_PAS_ID 13
@@ -1258,6 +1259,7 @@  static void a6xx_recover(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
 	int i, active_submits;
 
 	adreno_dump_info(gpu);
@@ -1290,6 +1292,10 @@  static void a6xx_recover(struct msm_gpu *gpu)
 	 */
 	gpu->active_submits = 0;
 
+	reinit_completion(&gmu->pd_gate);
+	dev_pm_genpd_add_notifier(gmu->cxpd, &gmu->pd_nb);
+	dev_pm_genpd_synced_poweroff(gmu->cxpd);
+
 	/* Drop the rpm refcount from active submits */
 	if (active_submits)
 		pm_runtime_put(&gpu->pdev->dev);
@@ -1297,6 +1303,11 @@  static void a6xx_recover(struct msm_gpu *gpu)
 	/* And the final one from recover worker */
 	pm_runtime_put_sync(&gpu->pdev->dev);
 
+	if (!wait_for_completion_timeout(&gmu->pd_gate, msecs_to_jiffies(1000)))
+		DRM_DEV_ERROR(&gpu->pdev->dev, "cx gdsc didn't collapse\n");
+
+	dev_pm_genpd_remove_notifier(gmu->cxpd);
+
 	pm_runtime_use_autosuspend(&gpu->pdev->dev);
 
 	if (active_submits)