From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:32:34
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
Lucas Stach (12):
soc: imx: gpcv2: move to more ideomatic error handling in probe
soc: imx: gpcv2: move domain mapping to domain driver probe
soc: imx: gpcv2: switch to clk_bulk_* API
soc: imx: gpcv2: split power up and power down sequence control
soc: imx: gpcv2: wait for ADB400 handshake
soc: imx: gpcv2: add runtime PM support for power-domains
soc: imx: gpcv2: allow domains without power-sequence control
dt-bindings: imx: gpcv2: add support for optional resets
soc: imx: gpcv2: add support for optional resets
dt-bindings: power: add defines for i.MX8MM power domains
soc: imx: gpcv2: add support for i.MX8MM power domains
soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
domains
Peng Fan (1):
soc: imx: gpcv2: move reset assert after requesting domain power up
.../bindings/power/fsl,imx-gpcv2.yaml | 9 +
drivers/soc/imx/gpcv2.c | 542 ++++++++++++++----
include/dt-bindings/power/imx8mm-power.h | 22 +
3 files changed, 458 insertions(+), 115 deletions(-)
create mode 100644 include/dt-bindings/power/imx8mm-power.h
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:32:38
From: Lucas Stach <l.stach@pengutronix.de>
Switch to "goto out..." error handling in domain driver probe to
avoid repeating all the error paths.
Reviewed-by: Marek Vasut <marex@denx.de>
Reviewed-by: Frieder Schrempf <redacted>
Tested-by: Adam Ford <redacted>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
@@ -502,18 +502,23 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)ret=pm_genpd_init(&domain->genpd,NULL,true);if(ret){dev_err(domain->dev,"Failed to init power domain\n");-imx_pgc_put_clocks(domain);-returnret;+gotoout_put_clocks;}ret=of_genpd_add_provider_simple(domain->dev->of_node,&domain->genpd);if(ret){dev_err(domain->dev,"Failed to add genpd provider\n");-pm_genpd_remove(&domain->genpd);-imx_pgc_put_clocks(domain);+gotoout_genpd_remove;}+return0;++out_genpd_remove:+pm_genpd_remove(&domain->genpd);+out_put_clocks:+imx_pgc_put_clocks(domain);+returnret;}
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:32:43
From: Lucas Stach <l.stach@pengutronix.de>
As long as the power domain driver is active we want power control
over the domain (which is what the mapping bit requests), so there
is no point in whacking it for every power control action, simply
set the bit in driver probe and clear it when the driver is removed.
Reviewed-by: Frieder Schrempf <redacted>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/soc/imx/gpcv2.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
@@ -499,10 +494,13 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)if(ret)returndev_err_probe(domain->dev,ret,"Failed to get domain's clocks\n");+regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,+domain->bits.map,domain->bits.map);+ret=pm_genpd_init(&domain->genpd,NULL,true);if(ret){dev_err(domain->dev,"Failed to init power domain\n");-gotoout_put_clocks;+gotoout_domain_unmap;}ret=of_genpd_add_provider_simple(domain->dev->of_node,
@@ -516,7 +514,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)out_genpd_remove:pm_genpd_remove(&domain->genpd);-out_put_clocks:+out_domain_unmap:+regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,+domain->bits.map,0);imx_pgc_put_clocks(domain);returnret;
@@ -528,6 +528,10 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)of_genpd_del_provider(domain->dev->of_node);pm_genpd_remove(&domain->genpd);++regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,+domain->bits.map,0);+imx_pgc_put_clocks(domain);return0;
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:32:49
From: Lucas Stach <l.stach@pengutronix.de>
Use clk_bulk API to simplify the code a bit. Also add some error
checking to the clk_prepare_enable calls.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 60 +++++++++--------------------------------
1 file changed, 12 insertions(+), 48 deletions(-)
@@ -149,8 +147,12 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,}/* Enable reset clocks for all devices in the domain */-for(i=0;i<domain->num_clks;i++)-clk_prepare_enable(domain->clk[i]);+ret=clk_bulk_prepare_enable(domain->num_clks,domain->clks);+if(ret){+dev_err(domain->dev,"failed to enable reset clocks\n");+regulator_disable(domain->regulator);+returnret;+}if(enable_power_control)regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),
@@ -187,8 +189,7 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,GPC_PGC_CTRL_PCR,0);/* Disable reset clocks for all devices in the domain */-for(i=0;i<domain->num_clks;i++)-clk_disable_unprepare(domain->clk[i]);+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);if(has_regulator&&!on){interr;
@@ -490,9 +456,10 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)domain->voltage,domain->voltage);}-ret=imx_pgc_get_clocks(domain);-if(ret)-returndev_err_probe(domain->dev,ret,"Failed to get domain's clocks\n");+domain->num_clks=devm_clk_bulk_get_all(domain->dev,&domain->clks);+if(domain->num_clks<0)+returndev_err_probe(domain->dev,domain->num_clks,+"Failed to get domain's clocks\n");regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,domain->bits.map);
@@ -517,7 +484,6 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)out_domain_unmap:regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,0);-imx_pgc_put_clocks(domain);returnret;}
@@ -532,8 +498,6 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,0);-imx_pgc_put_clocks(domain);-return0;}
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:32:56
From: Lucas Stach <l.stach@pengutronix.de>
The current mixed function to control both power up and power down
sequences is very hard to follow and already contains some sequence
errors like triggering the ADB400 handshake at the wrong time due to
this. Split the function into two, which results in slightly more
code, but is way easier to get right.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 141 ++++++++++++++++++++++++----------------
1 file changed, 86 insertions(+), 55 deletions(-)
@@ -125,20 +125,19 @@ struct imx_pgc_domain_data {conststructregmap_access_table*reg_access_table;};-staticintimx_gpc_pu_pgc_sw_pxx_req(structgeneric_pm_domain*genpd,-boolon)+staticinlinestructimx_pgc_domain*+to_imx_pgc_domain(structgeneric_pm_domain*genpd){-structimx_pgc_domain*domain=container_of(genpd,-structimx_pgc_domain,-genpd);-unsignedintoffset=on?-GPC_PU_PGC_SW_PUP_REQ:GPC_PU_PGC_SW_PDN_REQ;-constboolenable_power_control=!on;-constboolhas_regulator=!IS_ERR(domain->regulator);-inti,ret=0;-u32pxx_req;--if(has_regulator&&on){+returncontainer_of(genpd,structimx_pgc_domain,genpd);+}++staticintimx_pgc_power_up(structgeneric_pm_domain*genpd)+{+structimx_pgc_domain*domain=to_imx_pgc_domain(genpd);+u32reg_val;+intret;++if(!IS_ERR(domain->regulator)){ret=regulator_enable(domain->regulator);if(ret){dev_err(domain->dev,"failed to enable regulator\n");
@@ -150,69 +149,101 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,ret=clk_bulk_prepare_enable(domain->num_clks,domain->clks);if(ret){dev_err(domain->dev,"failed to enable reset clocks\n");-regulator_disable(domain->regulator);-returnret;+gotoout_regulator_disable;}-if(enable_power_control)-regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),-GPC_PGC_CTRL_PCR,GPC_PGC_CTRL_PCR);--if(domain->bits.hsk)-regmap_update_bits(domain->regmap,GPC_PU_PWRHSK,-domain->bits.hsk,on?domain->bits.hsk:0);--regmap_update_bits(domain->regmap,offset,+/* request the domain to power up */+regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,domain->bits.pxx,domain->bits.pxx);-/**Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait*forPUP_REQ/PDN_REQbittobecleared*/-ret=regmap_read_poll_timeout(domain->regmap,offset,pxx_req,-!(pxx_req&domain->bits.pxx),+ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,+reg_val,!(reg_val&domain->bits.pxx),0,USEC_PER_MSEC);if(ret){dev_err(domain->dev,"failed to command PGC\n");-/*-*Ifwewereinaprocessofenablinga-*domainandfailedwemightaswelldisable-*theregulatorwejustenabled.Andifit-*wastheoppositesituationandwefailedto-*powerdown--keeptheregulatoron-*/-on=!on;+gotoout_clk_disable;}-if(enable_power_control)-regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),-GPC_PGC_CTRL_PCR,0);+/* disable power control */+regmap_clear_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),+GPC_PGC_CTRL_PCR);++/* request the ADB400 to power up */+if(domain->bits.hsk)+regmap_update_bits(domain->regmap,GPC_PU_PWRHSK,+domain->bits.hsk,domain->bits.hsk);/* Disable reset clocks for all devices in the domain */clk_bulk_disable_unprepare(domain->num_clks,domain->clks);-if(has_regulator&&!on){-interr;+return0;-err=regulator_disable(domain->regulator);-if(err)-dev_err(domain->dev,-"failed to disable regulator: %d\n",err);-/* Preserve earlier error code */-ret=ret?:err;-}+out_clk_disable:+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);+out_regulator_disable:+if(!IS_ERR(domain->regulator))+regulator_disable(domain->regulator);returnret;}-staticintimx_gpc_pu_pgc_sw_pup_req(structgeneric_pm_domain*genpd)+staticintimx_pgc_power_down(structgeneric_pm_domain*genpd){-returnimx_gpc_pu_pgc_sw_pxx_req(genpd,true);-}+structimx_pgc_domain*domain=to_imx_pgc_domain(genpd);+u32reg_val;+intret;-staticintimx_gpc_pu_pgc_sw_pdn_req(structgeneric_pm_domain*genpd)-{-returnimx_gpc_pu_pgc_sw_pxx_req(genpd,false);+/* Enable reset clocks for all devices in the domain */+ret=clk_bulk_prepare_enable(domain->num_clks,domain->clks);+if(ret){+dev_err(domain->dev,"failed to enable reset clocks\n");+returnret;+}++/* request the ADB400 to power down */+if(domain->bits.hsk)+regmap_clear_bits(domain->regmap,GPC_PU_PWRHSK,+domain->bits.hsk);++/* enable power control */+regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),+GPC_PGC_CTRL_PCR,GPC_PGC_CTRL_PCR);++/* request the domain to power down */+regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,+domain->bits.pxx,domain->bits.pxx);+/*+*Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait+*forPUP_REQ/PDN_REQbittobecleared+*/+ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,+reg_val,!(reg_val&domain->bits.pxx),+0,USEC_PER_MSEC);+if(ret){+dev_err(domain->dev,"failed to command PGC\n");+gotoout_clk_disable;+}++/* Disable reset clocks for all devices in the domain */+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);++if(!IS_ERR(domain->regulator)){+ret=regulator_disable(domain->regulator);+if(ret){+dev_err(domain->dev,"failed to disable regulator\n");+returnret;+}+}++return0;++out_clk_disable:+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);++returnret;}staticconststructimx_pgc_domainimx7_pgc_domains[]={
@@ -590,8 +621,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev)domain=pd_pdev->dev.platform_data;domain->regmap=regmap;-domain->genpd.power_on=imx_gpc_pu_pgc_sw_pup_req;-domain->genpd.power_off=imx_gpc_pu_pgc_sw_pdn_req;+domain->genpd.power_on=imx_pgc_power_up;+domain->genpd.power_off=imx_pgc_power_down;pd_pdev->dev.parent=dev;pd_pdev->dev.of_node=np;
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:01
From: Lucas Stach <l.stach@pengutronix.de>
New reference manuals show that there is actually a status bit for
the ADB400 handshake. Add a poll loop to wait for the ADB400 to
acknowledge our request.
[Peng Fan: i.MX8MM has blk ctl module, the handshake can only finish
after setting blk ctl. The blk ctl driver will set the bus clk bit and
the handshake will finish there. we just add a delay and suppose the
handshake will finish after that.]
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/soc/imx/gpcv2.c | 47 ++++++++++++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 8 deletions(-)
@@ -172,9 +176,23 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)GPC_PGC_CTRL_PCR);/* request the ADB400 to power up */-if(domain->bits.hsk)+if(domain->bits.hskreq){regmap_update_bits(domain->regmap,GPC_PU_PWRHSK,-domain->bits.hsk,domain->bits.hsk);+domain->bits.hskreq,domain->bits.hskreq);++/*+*ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PWRHSK,reg_val,+*(reg_val&domain->bits.hskack),0,+*USEC_PER_MSEC);+*Technicallyweneedthecommentedcodetowaithandshake.Butthatneeds+*theBLK-CTLmoduleBUSclk-enbitbeingset.+*+*ThereisaseparateBLK-CTLmoduleandwewillhavesuchadriverforit,+*thatdriverwillsettheBUSclk-enbitandhandshakewillbetriggered+*automaticallythere.Justaddadelayandsupposethehandshakefinish+*afterthat.+*/+}/* Disable reset clocks for all devices in the domain */clk_bulk_disable_unprepare(domain->num_clks,domain->clks);
@@ -204,9 +222,19 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)}/* request the ADB400 to power down */-if(domain->bits.hsk)+if(domain->bits.hskreq){regmap_clear_bits(domain->regmap,GPC_PU_PWRHSK,-domain->bits.hsk);+domain->bits.hskreq);++ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PWRHSK,+reg_val,+!(reg_val&domain->bits.hskack),+0,USEC_PER_MSEC);+if(ret){+dev_err(domain->dev,"failed to power down ADB400\n");+gotoout_clk_disable;+}+}/* enable power control */regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:17
From: Lucas Stach <l.stach@pengutronix.de>
This allows to nest domains into other power domains and have the
parent domain powered up/down as required by the child domains.
Reviewed-by: Frieder Schrempf <redacted>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
@@ -141,11 +142,17 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)u32reg_val;intret;+ret=pm_runtime_get_sync(domain->dev);+if(ret<0){+pm_runtime_put_noidle(domain->dev);+returnret;+}+if(!IS_ERR(domain->regulator)){ret=regulator_enable(domain->regulator);if(ret){dev_err(domain->dev,"failed to enable regulator\n");-returnret;+gotoout_put_pm;}}
@@ -204,6 +211,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)out_regulator_disable:if(!IS_ERR(domain->regulator))regulator_disable(domain->regulator);+out_put_pm:+pm_runtime_put(domain->dev);returnret;}
@@ -266,6 +275,8 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)}}+pm_runtime_put(domain->dev);+return0;out_clk_disable:
@@ -523,6 +534,8 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)returndev_err_probe(domain->dev,domain->num_clks,"Failed to get domain's clocks\n");+pm_runtime_enable(domain->dev);+regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,domain->bits.map);
@@ -546,6 +559,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)out_domain_unmap:regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,0);+pm_runtime_disable(domain->dev);returnret;}
@@ -560,6 +574,8 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,0);+pm_runtime_disable(domain->dev);+return0;}
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:20
From: Lucas Stach <l.stach@pengutronix.de>
Some of the PGC domains only control the handshake with the ADB400
and don't have any power sequence controls. Make such domains work
by allowing the pxx and map bits to be empty and skip all actions
using those controls.
Reviewed-by: Frieder Schrempf <redacted>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 89 +++++++++++++++++++++++------------------
1 file changed, 49 insertions(+), 40 deletions(-)
@@ -163,24 +163,27 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)gotoout_regulator_disable;}-/* request the domain to power up */-regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,-domain->bits.pxx,domain->bits.pxx);-/*-*Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait-*forPUP_REQ/PDN_REQbittobecleared-*/-ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,-reg_val,!(reg_val&domain->bits.pxx),-0,USEC_PER_MSEC);-if(ret){-dev_err(domain->dev,"failed to command PGC\n");-gotoout_clk_disable;-}+if(domain->bits.pxx){+/* request the domain to power up */+regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,+domain->bits.pxx,domain->bits.pxx);+/*+*Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait+*forPUP_REQ/PDN_REQbittobecleared+*/+ret=regmap_read_poll_timeout(domain->regmap,+GPC_PU_PGC_SW_PUP_REQ,reg_val,+!(reg_val&domain->bits.pxx),+0,USEC_PER_MSEC);+if(ret){+dev_err(domain->dev,"failed to command PGC\n");+gotoout_clk_disable;+}-/* disable power control */-regmap_clear_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),-GPC_PGC_CTRL_PCR);+/* disable power control */+regmap_clear_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),+GPC_PGC_CTRL_PCR);+}/* request the ADB400 to power up */if(domain->bits.hskreq){
@@ -245,23 +248,26 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)}}-/* enable power control */-regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),-GPC_PGC_CTRL_PCR,GPC_PGC_CTRL_PCR);--/* request the domain to power down */-regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,-domain->bits.pxx,domain->bits.pxx);-/*-*Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait-*forPUP_REQ/PDN_REQbittobecleared-*/-ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,-reg_val,!(reg_val&domain->bits.pxx),-0,USEC_PER_MSEC);-if(ret){-dev_err(domain->dev,"failed to command PGC\n");-gotoout_clk_disable;+if(domain->bits.pxx){+/* enable power control */+regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),+GPC_PGC_CTRL_PCR,GPC_PGC_CTRL_PCR);++/* request the domain to power down */+regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,+domain->bits.pxx,domain->bits.pxx);+/*+*Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait+*forPUP_REQ/PDN_REQbittobecleared+*/+ret=regmap_read_poll_timeout(domain->regmap,+GPC_PU_PGC_SW_PDN_REQ,reg_val,+!(reg_val&domain->bits.pxx),+0,USEC_PER_MSEC);+if(ret){+dev_err(domain->dev,"failed to command PGC\n");+gotoout_clk_disable;+}}/* Disable reset clocks for all devices in the domain */
@@ -536,8 +542,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)pm_runtime_enable(domain->dev);-regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,-domain->bits.map,domain->bits.map);+if(domain->bits.map)+regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,+domain->bits.map,domain->bits.map);ret=pm_genpd_init(&domain->genpd,NULL,true);if(ret){
@@ -557,8 +564,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)out_genpd_remove:pm_genpd_remove(&domain->genpd);out_domain_unmap:-regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,-domain->bits.map,0);+if(domain->bits.map)+regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,+domain->bits.map,0);pm_runtime_disable(domain->dev);returnret;
@@ -571,8 +579,9 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)of_genpd_del_provider(domain->dev->of_node);pm_genpd_remove(&domain->genpd);-regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,-domain->bits.map,0);+if(domain->bits.map)+regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,+domain->bits.map,0);pm_runtime_disable(domain->dev);
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:27
From: Lucas Stach <l.stach@pengutronix.de>
For some domains the resets of the devices in the domain are not
automatically triggered. Add an optional resets property to allow
the GPC driver to trigger those resets explicitly.
The resets belong to devices located inside the power domain,
which need to be held in reset across the power-up sequence. So we
have no means to specify what each reset is in a generic power-domain
binding. Same situation as with the clocks in this binding actually.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml | 7 +++++++
1 file changed, 7 insertions(+)
@@ -66,6 +66,13 @@ properties:power-supply:true+resets:+description:|+A number of phandles to resets that need to be asserted during+power-up sequencing of the domain.+minItems:1+maxItems:4+required:-'#power-domain-cells'-reg
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:31
From: Lucas Stach <l.stach@pengutronix.de>
Normally the reset for the devices inside the power domain is
triggered automatically from the PGC in the power-up sequencing,
however on i.MX8MM this doesn't work for the GPU power domains.
Add support for triggering the reset explicitly during the power
up sequencing.
Reviewed-by: Frieder Schrempf <redacted>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -163,6 +165,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)gotoout_regulator_disable;}+reset_control_assert(domain->reset);+if(domain->bits.pxx){/* request the domain to power up */regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,
@@ -185,6 +189,11 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)GPC_PGC_CTRL_PCR);}+/* delay for reset to propagate */+udelay(5);++reset_control_deassert(domain->reset);+/* request the ADB400 to power up */if(domain->bits.hskreq){regmap_update_bits(domain->regmap,GPC_PU_PWRHSK,
@@ -540,6 +549,11 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)returndev_err_probe(domain->dev,domain->num_clks,"Failed to get domain's clocks\n");+domain->reset=devm_reset_control_array_get_optional_exclusive(domain->dev);+if(IS_ERR(domain->reset))+returndev_err_probe(domain->dev,PTR_ERR(domain->reset),+"Failed to get domain's resets\n");+pm_runtime_enable(domain->dev);if(domain->bits.map)
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
@@ -54,6 +55,7 @@ properties:Power domain index. Valid values are defined ininclude/dt-bindings/power/imx7-power.h for fsl,imx7d-gpc andinclude/dt-bindings/power/imx8m-power.h for fsl,imx8mq-gpc+include/dt-bindings/power/imx8mm-power.h for fsl,imx8mm-gpcmaxItems:1clocks:
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:39
From: Lucas Stach <l.stach@pengutronix.de>
This adds support for the power domains found on i.MX8MM. The 2D and 3D
GPU domains are abstracted as a single domain in the driver, as they can't
be powered up/down individually due to a shared reset.
Reviewed-by: Frieder Schrempf <redacted>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 168 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 168 insertions(+)
@@ -527,6 +579,121 @@ static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {.reg_access_table=&imx8m_access_table,};+staticconststructimx_pgc_domainimx8mm_pgc_domains[]={+[IMX8MM_POWER_DOMAIN_HSIOMIX]={+.genpd={+.name="hsiomix",+},+.bits={+.pxx=0,/* no power sequence control */+.map=0,/* no power sequence control */+.hskreq=IMX8MM_HSIO_HSK_PWRDNREQN,+.hskack=IMX8MM_HSIO_HSK_PWRDNACKN,+},+},++[IMX8MM_POWER_DOMAIN_PCIE]={+.genpd={+.name="pcie",+},+.bits={+.pxx=IMX8MM_PCIE_SW_Pxx_REQ,+.map=IMX8MM_PCIE_A53_DOMAIN,+},+.pgc=IMX8MM_PGC_PCIE,+},++[IMX8MM_POWER_DOMAIN_OTG1]={+.genpd={+.name="usb-otg1",+},+.bits={+.pxx=IMX8MM_OTG1_SW_Pxx_REQ,+.map=IMX8MM_OTG1_A53_DOMAIN,+},+.pgc=IMX8MM_PGC_OTG1,+},++[IMX8MM_POWER_DOMAIN_OTG2]={+.genpd={+.name="usb-otg2",+},+.bits={+.pxx=IMX8MM_OTG2_SW_Pxx_REQ,+.map=IMX8MM_OTG2_A53_DOMAIN,+},+.pgc=IMX8MM_PGC_OTG2,+},++[IMX8MM_POWER_DOMAIN_GPUMIX]={+.genpd={+.name="gpumix",+},+.bits={+.pxx=IMX8MM_GPUMIX_SW_Pxx_REQ,+.map=IMX8MM_GPUMIX_A53_DOMAIN,+.hskreq=IMX8MM_GPUMIX_HSK_PWRDNREQN,+.hskack=IMX8MM_GPUMIX_HSK_PWRDNACKN,+},+.pgc=IMX8MM_PGC_GPUMIX,+},++[IMX8MM_POWER_DOMAIN_GPU]={+.genpd={+.name="gpu",+},+.bits={+.pxx=IMX8MM_GPU_SW_Pxx_REQ,+.map=IMX8MM_GPU_A53_DOMAIN,+.hskreq=IMX8MM_GPU_HSK_PWRDNREQN,+.hskack=IMX8MM_GPU_HSK_PWRDNACKN,+},+.pgc=IMX8MM_PGC_GPU2D,+},+};++staticconststructregmap_rangeimx8mm_yes_ranges[]={+regmap_reg_range(GPC_LPCR_A_CORE_BSC,+GPC_PU_PWRHSK),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_MIPI),+GPC_PGC_SR(IMX8MM_PGC_MIPI)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_PCIE),+GPC_PGC_SR(IMX8MM_PGC_PCIE)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG1),+GPC_PGC_SR(IMX8MM_PGC_OTG1)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG2),+GPC_PGC_SR(IMX8MM_PGC_OTG2)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DDR1),+GPC_PGC_SR(IMX8MM_PGC_DDR1)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU2D),+GPC_PGC_SR(IMX8MM_PGC_GPU2D)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPUMIX),+GPC_PGC_SR(IMX8MM_PGC_GPUMIX)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUMIX),+GPC_PGC_SR(IMX8MM_PGC_VPUMIX)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU3D),+GPC_PGC_SR(IMX8MM_PGC_GPU3D)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DISPMIX),+GPC_PGC_SR(IMX8MM_PGC_DISPMIX)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG1),+GPC_PGC_SR(IMX8MM_PGC_VPUG1)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG2),+GPC_PGC_SR(IMX8MM_PGC_VPUG2)),+regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUH1),+GPC_PGC_SR(IMX8MM_PGC_VPUH1)),+};++staticconststructregmap_access_tableimx8mm_access_table={+.yes_ranges=imx8mm_yes_ranges,+.n_yes_ranges=ARRAY_SIZE(imx8mm_yes_ranges),+};++staticconststructimx_pgc_domain_dataimx8mm_pgc_domain_data={+.domains=imx8mm_pgc_domains,+.domains_num=ARRAY_SIZE(imx8mm_pgc_domains),+.reg_access_table=&imx8mm_access_table,+};+staticintimx_pgc_domain_probe(structplatform_device*pdev){structimx_pgc_domain*domain=pdev->dev.platform_data;
@@ -710,6 +877,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)staticconststructof_device_idimx_gpcv2_dt_ids[]={{.compatible="fsl,imx7d-gpc",.data=&imx7_pgc_domain_data,},+{.compatible="fsl,imx8mm-gpc",.data=&imx8mm_pgc_domain_data,},{.compatible="fsl,imx8mq-gpc",.data=&imx8m_pgc_domain_data,},{}};
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:52
From: Lucas Stach <l.stach@pengutronix.de>
With the BLK-CTL driver now in place, let's add the missing domains.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Frieder Schrempf <redacted>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 70 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
From: Peng Fan (OSS) <hidden> Date: 2021-05-06 00:33:54
From: Peng Fan <peng.fan@nxp.com>
The i.MX8MM VPU power up sequence is a bit special, it must follow:
1. request power up
2. reset assert
3. reset deassert
This change in this patch will not affect other domains, because
the power domain default is in asserted state, unless bootloader
deassert the reset. It also applies to GPU power domain.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/soc/imx/gpcv2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -217,8 +217,6 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)gotoout_regulator_disable;}-reset_control_assert(domain->reset);-if(domain->bits.pxx){/* request the domain to power up */regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,
@@ -241,6 +239,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)GPC_PGC_CTRL_PCR);}+reset_control_assert(domain->reset);+/* delay for reset to propagate */udelay(5);
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Lucas Stach <l.stach@pengutronix.de>
Use clk_bulk API to simplify the code a bit. Also add some error
checking to the clk_prepare_enable calls.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
@@ -149,8 +147,12 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,}/* Enable reset clocks for all devices in the domain */-for(i=0;i<domain->num_clks;i++)-clk_prepare_enable(domain->clk[i]);+ret=clk_bulk_prepare_enable(domain->num_clks,domain->clks);+if(ret){+dev_err(domain->dev,"failed to enable reset clocks\n");+regulator_disable(domain->regulator);+returnret;+}if(enable_power_control)regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),
@@ -187,8 +189,7 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,GPC_PGC_CTRL_PCR,0);/* Disable reset clocks for all devices in the domain */-for(i=0;i<domain->num_clks;i++)-clk_disable_unprepare(domain->clk[i]);+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);if(has_regulator&&!on){interr;
@@ -490,9 +456,10 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)domain->voltage,domain->voltage);}-ret=imx_pgc_get_clocks(domain);-if(ret)-returndev_err_probe(domain->dev,ret,"Failed to get domain's clocks\n");+domain->num_clks=devm_clk_bulk_get_all(domain->dev,&domain->clks);+if(domain->num_clks<0)+returndev_err_probe(domain->dev,domain->num_clks,+"Failed to get domain's clocks\n");regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,domain->bits.map);
@@ -517,7 +484,6 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)out_domain_unmap:regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,0);-imx_pgc_put_clocks(domain);returnret;}
@@ -532,8 +498,6 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)regmap_update_bits(domain->regmap,GPC_PGC_CPU_MAPPING,domain->bits.map,0);-imx_pgc_put_clocks(domain);-return0;}
From: Lucas Stach <l.stach@pengutronix.de>
The current mixed function to control both power up and power down
sequences is very hard to follow and already contains some sequence
errors like triggering the ADB400 handshake at the wrong time due to
this. Split the function into two, which results in slightly more
code, but is way easier to get right.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
@@ -125,20 +125,19 @@ struct imx_pgc_domain_data {conststructregmap_access_table*reg_access_table;};-staticintimx_gpc_pu_pgc_sw_pxx_req(structgeneric_pm_domain*genpd,-boolon)+staticinlinestructimx_pgc_domain*+to_imx_pgc_domain(structgeneric_pm_domain*genpd){-structimx_pgc_domain*domain=container_of(genpd,-structimx_pgc_domain,-genpd);-unsignedintoffset=on?-GPC_PU_PGC_SW_PUP_REQ:GPC_PU_PGC_SW_PDN_REQ;-constboolenable_power_control=!on;-constboolhas_regulator=!IS_ERR(domain->regulator);-inti,ret=0;-u32pxx_req;--if(has_regulator&&on){+returncontainer_of(genpd,structimx_pgc_domain,genpd);+}++staticintimx_pgc_power_up(structgeneric_pm_domain*genpd)+{+structimx_pgc_domain*domain=to_imx_pgc_domain(genpd);+u32reg_val;+intret;++if(!IS_ERR(domain->regulator)){ret=regulator_enable(domain->regulator);if(ret){dev_err(domain->dev,"failed to enable regulator\n");
@@ -150,69 +149,101 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,ret=clk_bulk_prepare_enable(domain->num_clks,domain->clks);if(ret){dev_err(domain->dev,"failed to enable reset clocks\n");-regulator_disable(domain->regulator);-returnret;+gotoout_regulator_disable;}-if(enable_power_control)-regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),-GPC_PGC_CTRL_PCR,GPC_PGC_CTRL_PCR);--if(domain->bits.hsk)-regmap_update_bits(domain->regmap,GPC_PU_PWRHSK,-domain->bits.hsk,on?domain->bits.hsk:0);--regmap_update_bits(domain->regmap,offset,+/* request the domain to power up */+regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,domain->bits.pxx,domain->bits.pxx);-/**Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait*forPUP_REQ/PDN_REQbittobecleared*/-ret=regmap_read_poll_timeout(domain->regmap,offset,pxx_req,-!(pxx_req&domain->bits.pxx),+ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,+reg_val,!(reg_val&domain->bits.pxx),0,USEC_PER_MSEC);if(ret){dev_err(domain->dev,"failed to command PGC\n");-/*-*Ifwewereinaprocessofenablinga-*domainandfailedwemightaswelldisable-*theregulatorwejustenabled.Andifit-*wastheoppositesituationandwefailedto-*powerdown--keeptheregulatoron-*/-on=!on;+gotoout_clk_disable;}-if(enable_power_control)-regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),-GPC_PGC_CTRL_PCR,0);+/* disable power control */+regmap_clear_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),+GPC_PGC_CTRL_PCR);++/* request the ADB400 to power up */+if(domain->bits.hsk)+regmap_update_bits(domain->regmap,GPC_PU_PWRHSK,+domain->bits.hsk,domain->bits.hsk);/* Disable reset clocks for all devices in the domain */clk_bulk_disable_unprepare(domain->num_clks,domain->clks);-if(has_regulator&&!on){-interr;+return0;-err=regulator_disable(domain->regulator);-if(err)-dev_err(domain->dev,-"failed to disable regulator: %d\n",err);-/* Preserve earlier error code */-ret=ret?:err;-}+out_clk_disable:+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);+out_regulator_disable:+if(!IS_ERR(domain->regulator))+regulator_disable(domain->regulator);returnret;}-staticintimx_gpc_pu_pgc_sw_pup_req(structgeneric_pm_domain*genpd)+staticintimx_pgc_power_down(structgeneric_pm_domain*genpd){-returnimx_gpc_pu_pgc_sw_pxx_req(genpd,true);-}+structimx_pgc_domain*domain=to_imx_pgc_domain(genpd);+u32reg_val;+intret;-staticintimx_gpc_pu_pgc_sw_pdn_req(structgeneric_pm_domain*genpd)-{-returnimx_gpc_pu_pgc_sw_pxx_req(genpd,false);+/* Enable reset clocks for all devices in the domain */+ret=clk_bulk_prepare_enable(domain->num_clks,domain->clks);+if(ret){+dev_err(domain->dev,"failed to enable reset clocks\n");+returnret;+}++/* request the ADB400 to power down */+if(domain->bits.hsk)+regmap_clear_bits(domain->regmap,GPC_PU_PWRHSK,+domain->bits.hsk);++/* enable power control */+regmap_update_bits(domain->regmap,GPC_PGC_CTRL(domain->pgc),+GPC_PGC_CTRL_PCR,GPC_PGC_CTRL_PCR);++/* request the domain to power down */+regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,+domain->bits.pxx,domain->bits.pxx);+/*+*Asper"5.5.9.4 Example Code 4"inIMX7DRM.pdfwait+*forPUP_REQ/PDN_REQbittobecleared+*/+ret=regmap_read_poll_timeout(domain->regmap,GPC_PU_PGC_SW_PDN_REQ,+reg_val,!(reg_val&domain->bits.pxx),+0,USEC_PER_MSEC);+if(ret){+dev_err(domain->dev,"failed to command PGC\n");+gotoout_clk_disable;+}++/* Disable reset clocks for all devices in the domain */+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);++if(!IS_ERR(domain->regulator)){+ret=regulator_disable(domain->regulator);+if(ret){+dev_err(domain->dev,"failed to disable regulator\n");+returnret;+}+}++return0;++out_clk_disable:+clk_bulk_disable_unprepare(domain->num_clks,domain->clks);++returnret;}staticconststructimx_pgc_domainimx7_pgc_domains[]={
@@ -590,8 +621,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev)domain=pd_pdev->dev.platform_data;domain->regmap=regmap;-domain->genpd.power_on=imx_gpc_pu_pgc_sw_pup_req;-domain->genpd.power_off=imx_gpc_pu_pgc_sw_pdn_req;+domain->genpd.power_on=imx_pgc_power_up;+domain->genpd.power_off=imx_pgc_power_down;pd_pdev->dev.parent=dev;pd_pdev->dev.of_node=np;
From: Lucas Stach <l.stach@pengutronix.de>
For some domains the resets of the devices in the domain are not
automatically triggered. Add an optional resets property to allow
the GPC driver to trigger those resets explicitly.
The resets belong to devices located inside the power domain,
which need to be held in reset across the power-up sequence. So we
have no means to specify what each reset is in a generic power-domain
binding. Same situation as with the clocks in this binding actually.
My understanding was that Rob wanted this explanation to be contained in the binding docs itself and not only in the commit message, but I might be wrong.
quoted hunk
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml | 7 +++++++
1 file changed, 7 insertions(+)
@@ -66,6 +66,13 @@ properties:power-supply:true+resets:+description:|+A number of phandles to resets that need to be asserted during+power-up sequencing of the domain.+minItems:1+maxItems:4+required:-'#power-domain-cells'-reg
From: Peng Fan <peng.fan@nxp.com>
The i.MX8MM VPU power up sequence is a bit special, it must follow:
1. request power up
2. reset assert
3. reset deassert
This change in this patch will not affect other domains, because
the power domain default is in asserted state, unless bootloader
deassert the reset. It also applies to GPU power domain.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
I don't really like that there is a dependency on TF-A/bootloader as we never really know what they will do, but from my point of view the approach is ok and it seems to work properly as far as I have tested it (only with GPU).
Reviewed-by: Frieder Schrempf <redacted>
Tested-by: Frieder Schrempf <redacted>
@@ -217,8 +217,6 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)gotoout_regulator_disable;}-reset_control_assert(domain->reset);-if(domain->bits.pxx){/* request the domain to power up */regmap_update_bits(domain->regmap,GPC_PU_PGC_SW_PUP_REQ,
@@ -241,6 +239,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)GPC_PGC_CTRL_PCR);}+reset_control_assert(domain->reset);+/* delay for reset to propagate */udelay(5);
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
I tested this series together with the BLK CTL patches by using the GPU and the display stack. Everything looks good to me.
Tested-by: Frieder Schrempf <redacted>
Lucas Stach (12):
soc: imx: gpcv2: move to more ideomatic error handling in probe
soc: imx: gpcv2: move domain mapping to domain driver probe
soc: imx: gpcv2: switch to clk_bulk_* API
soc: imx: gpcv2: split power up and power down sequence control
soc: imx: gpcv2: wait for ADB400 handshake
soc: imx: gpcv2: add runtime PM support for power-domains
soc: imx: gpcv2: allow domains without power-sequence control
dt-bindings: imx: gpcv2: add support for optional resets
soc: imx: gpcv2: add support for optional resets
dt-bindings: power: add defines for i.MX8MM power domains
soc: imx: gpcv2: add support for i.MX8MM power domains
soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
domains
Peng Fan (1):
soc: imx: gpcv2: move reset assert after requesting domain power up
.../bindings/power/fsl,imx-gpcv2.yaml | 9 +
drivers/soc/imx/gpcv2.c | 542 ++++++++++++++----
include/dt-bindings/power/imx8mm-power.h | 22 +
3 files changed, 458 insertions(+), 115 deletions(-)
create mode 100644 include/dt-bindings/power/imx8mm-power.h
From: Rob Herring <robh@kernel.org> Date: 2021-05-07 21:16:26
On Thu, May 06, 2021 at 08:43:17AM +0200, Frieder Schrempf wrote:
On 06.05.21 03:04, Peng Fan (OSS) wrote:
quoted
From: Lucas Stach <l.stach@pengutronix.de>
For some domains the resets of the devices in the domain are not
automatically triggered. Add an optional resets property to allow
the GPC driver to trigger those resets explicitly.
The resets belong to devices located inside the power domain,
which need to be held in reset across the power-up sequence. So we
have no means to specify what each reset is in a generic power-domain
binding. Same situation as with the clocks in this binding actually.
My understanding was that Rob wanted this explanation to be contained in the binding docs itself and not only in the commit message, but I might be wrong.
Yes, that would be better.
quoted
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml | 7 +++++++
1 file changed, 7 insertions(+)
@@ -66,6 +66,13 @@ properties:power-supply:true+resets:+description:|+A number of phandles to resets that need to be asserted during+power-up sequencing of the domain.+minItems:1+maxItems:4+required:-'#power-domain-cells'-reg
From: Peng Fan <peng.fan@nxp.com> Date: 2021-05-08 00:50:08
Subject: Re: [PATCH V2 08/13] dt-bindings: imx: gpcv2: add support for
optional resets
On Thu, May 06, 2021 at 08:43:17AM +0200, Frieder Schrempf wrote:
quoted
On 06.05.21 03:04, Peng Fan (OSS) wrote:
quoted
From: Lucas Stach <l.stach@pengutronix.de>
For some domains the resets of the devices in the domain are not
automatically triggered. Add an optional resets property to allow
the GPC driver to trigger those resets explicitly.
The resets belong to devices located inside the power domain, which
need to be held in reset across the power-up sequence. So we have no
means to specify what each reset is in a generic power-domain
binding. Same situation as with the clocks in this binding actually.
My understanding was that Rob wanted this explanation to be contained in
the binding docs itself and not only in the commit message, but I might be
wrong.
Yes, that would be better.
Sure, I will include that in V3.
Thanks,
Peng.
quoted
quoted
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml | 7
+++++++
1 file changed, 7 insertions(+)
diff --git
a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
index a96e6dbf1858..4330c73a2c30 100644
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
I tested this series together with the BLK CTL patches by using the GPU and the display stack. Everything looks good to me.
Tested-by: Frieder Schrempf <redacted>
So after some more testing on different hardware I stumbled upon the problem that USB autosuspend doesn't work properly anymore.
I have an onboard LTE module that is connected to OTG2 on the i.MX8MM. When using the mainline TF-A (that enables USB power-domains by default) and removing the power-domain control from the kernel, the device comes up after a few seconds and is enumerated on the bus.
Now, when I let the kernel control the power-domains, the device comes up at boot, but isn't enumerated on the USB bus. As soon as I disable autosuspend for the port, it comes up.
Is this something that needs to be fixed on the USB driver side or is something to be considered for the GPCv2 driver?
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
I tested this series together with the BLK CTL patches by using the GPU and the display stack. Everything looks good to me.
Tested-by: Frieder Schrempf <redacted>
So after some more testing on different hardware I stumbled upon the problem that USB autosuspend doesn't work properly anymore.
I have an onboard LTE module that is connected to OTG2 on the i.MX8MM. When using the mainline TF-A (that enables USB power-domains by default) and removing the power-domain control from the kernel, the device comes up after a few seconds and is enumerated on the bus.
Now, when I let the kernel control the power-domains, the device comes up at boot, but isn't enumerated on the USB bus. As soon as I disable autosuspend for the port, it comes up.
Is this something that needs to be fixed on the USB driver side or is something to be considered for the GPCv2 driver?
So I think this is something that needs to be covered on the USB driver side. I would expect that a device appearing on the bus should resume the autosuspended bus, but I don't really know much about USB so there might be other things I miss. For now I will disable autosuspend in this case.
A different, probably more severe problem is that I was still able to reliably run into lockups with suspend/resume and the GPU. I thought I had tested this before as it was one of the things that already failed with the previous implementation, but I must have missed something as it still fails with kernel v5.12.1 + v2 of the GPC patches.
This is how I run into the lockup:
echo mem > /sys/power/state # Sleep
# Wake up again
glmark2-es2-drm # Use the GPU
# Device locks up
Peng, is this something you can reproduce?
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Lucas Stach <l.stach@pengutronix.de> Date: 2021-07-21 20:51:58
Hi Frieder,
Am Donnerstag, dem 20.05.2021 um 17:16 +0200 schrieb Frieder Schrempf:
On 19.05.21 18:09, Frieder Schrempf wrote:
quoted
On 06.05.21 10:32, Frieder Schrempf wrote:
quoted
On 06.05.21 03:04, Peng Fan (OSS) wrote:
quoted
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5
to explain
details
- Add explaination in patch 8 for "why the resets are not
defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and
several
minor changes from me to make it could work with i.MX BLK-CTL
driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for
collecting
all the patches, Jacky Bai on help debug issues.
I tested this series together with the BLK CTL patches by using
the GPU and the display stack. Everything looks good to me.
Tested-by: Frieder Schrempf <redacted>
So after some more testing on different hardware I stumbled upon
the problem that USB autosuspend doesn't work properly anymore.
I have an onboard LTE module that is connected to OTG2 on the
i.MX8MM. When using the mainline TF-A (that enables USB power-
domains by default) and removing the power-domain control from the
kernel, the device comes up after a few seconds and is enumerated
on the bus.
Now, when I let the kernel control the power-domains, the device
comes up at boot, but isn't enumerated on the USB bus. As soon as I
disable autosuspend for the port, it comes up.
Is this something that needs to be fixed on the USB driver side or
is something to be considered for the GPCv2 driver?
So I think this is something that needs to be covered on the USB
driver side. I would expect that a device appearing on the bus should
resume the autosuspended bus, but I don't really know much about USB
so there might be other things I miss. For now I will disable
autosuspend in this case.
A different, probably more severe problem is that I was still able to
reliably run into lockups with suspend/resume and the GPU. I thought
I had tested this before as it was one of the things that already
failed with the previous implementation, but I must have missed
something as it still fails with kernel v5.12.1 + v2 of the GPC
patches.
This is how I run into the lockup:
echo mem > /sys/power/state # Sleep
# Wake up again
glmark2-es2-drm # Use the GPU
# Device locks up
Peng, is this something you can reproduce?
I could reproduce this issue on my last GPC+BLK_CTRL series. This was
caused by a bad interaction between our slightly unusual way to control
the nested power domains via runtime PM and the system suspend/resume
code, which lead to some of the power domains not properly coming up
again in the resume path. v2 of my series fixes this issue and the
above sequence works as expected.
Regards,
Lucas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Hi Frieder,
Am Donnerstag, dem 20.05.2021 um 17:16 +0200 schrieb Frieder Schrempf:
quoted
On 19.05.21 18:09, Frieder Schrempf wrote:
quoted
On 06.05.21 10:32, Frieder Schrempf wrote:
quoted
On 06.05.21 03:04, Peng Fan (OSS) wrote:
quoted
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5
to explain
details
- Add explaination in patch 8 for "why the resets are not
defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and
several
minor changes from me to make it could work with i.MX BLK-CTL
driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for
collecting
all the patches, Jacky Bai on help debug issues.
I tested this series together with the BLK CTL patches by using
the GPU and the display stack. Everything looks good to me.
Tested-by: Frieder Schrempf <redacted>
So after some more testing on different hardware I stumbled upon
the problem that USB autosuspend doesn't work properly anymore.
I have an onboard LTE module that is connected to OTG2 on the
i.MX8MM. When using the mainline TF-A (that enables USB power-
domains by default) and removing the power-domain control from the
kernel, the device comes up after a few seconds and is enumerated
on the bus.
Now, when I let the kernel control the power-domains, the device
comes up at boot, but isn't enumerated on the USB bus. As soon as I
disable autosuspend for the port, it comes up.
Is this something that needs to be fixed on the USB driver side or
is something to be considered for the GPCv2 driver?
So I think this is something that needs to be covered on the USB
driver side. I would expect that a device appearing on the bus should
resume the autosuspended bus, but I don't really know much about USB
so there might be other things I miss. For now I will disable
autosuspend in this case.
A different, probably more severe problem is that I was still able to
reliably run into lockups with suspend/resume and the GPU. I thought
I had tested this before as it was one of the things that already
failed with the previous implementation, but I must have missed
something as it still fails with kernel v5.12.1 + v2 of the GPC
patches.
This is how I run into the lockup:
echo mem > /sys/power/state # Sleep
# Wake up again
glmark2-es2-drm # Use the GPU
# Device locks up
Peng, is this something you can reproduce?
I could reproduce this issue on my last GPC+BLK_CTRL series. This was
caused by a bad interaction between our slightly unusual way to control
the nested power domains via runtime PM and the system suspend/resume
code, which lead to some of the power domains not properly coming up
again in the resume path. v2 of my series fixes this issue and the
above sequence works as expected.
Glad you could reproduce and fix this issue. Thanks for the effort. I will try to do some tests myself soon.
Thanks
Frieder
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Hi Peng, Lucas,
On Wed, 5 May 2021 at 21:32, Peng Fan (OSS) [off-list ref] wrote:
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
Lucas Stach (12):
soc: imx: gpcv2: move to more ideomatic error handling in probe
soc: imx: gpcv2: move domain mapping to domain driver probe
soc: imx: gpcv2: switch to clk_bulk_* API
soc: imx: gpcv2: split power up and power down sequence control
soc: imx: gpcv2: wait for ADB400 handshake
soc: imx: gpcv2: add runtime PM support for power-domains
soc: imx: gpcv2: allow domains without power-sequence control
dt-bindings: imx: gpcv2: add support for optional resets
soc: imx: gpcv2: add support for optional resets
dt-bindings: power: add defines for i.MX8MM power domains
soc: imx: gpcv2: add support for i.MX8MM power domains
soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
domains
It's nice to see this finally moving forward!
As you know, Hantro G2 support for i.MX8MQ (and i.MX8MP, i.MX8MM) is currently
blocked, as you have requested:
https://lore.kernel.org/driverdev-devel/5aa5700b862234895a7a6eb251ca3c80fdc1a6d3.camel@collabora.com/
So, I think we really need to include i.MX8MP and i.MX8MQ on this series.
It's been quite a while and we really need to have that. To be honest,
I fear that
if we merge this series as-is, MX8MP and MX8MP support will fall in
the oblivion,
and Hantro G2 VPU will remain unusable.
We are planning to submit Hantro G2 VP9 support soon, and we've been testing
on various platforms, but it will also be blocked by lack of power-domains.
In the future, please Cc the linux-media mailing list, as well as
Benjamin, Andrzej and myself, so we can follow this.
Thanks a lot for the hard work!
Ezequiel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Lucas Stach <l.stach@pengutronix.de> Date: 2021-08-09 08:16:36
Hi Ezequiel,
Am Mittwoch, dem 04.08.2021 um 11:30 -0300 schrieb Ezequiel Garcia:
Hi Peng, Lucas,
On Wed, 5 May 2021 at 21:32, Peng Fan (OSS) [off-list ref] wrote:
quoted
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
Lucas Stach (12):
soc: imx: gpcv2: move to more ideomatic error handling in probe
soc: imx: gpcv2: move domain mapping to domain driver probe
soc: imx: gpcv2: switch to clk_bulk_* API
soc: imx: gpcv2: split power up and power down sequence control
soc: imx: gpcv2: wait for ADB400 handshake
soc: imx: gpcv2: add runtime PM support for power-domains
soc: imx: gpcv2: allow domains without power-sequence control
dt-bindings: imx: gpcv2: add support for optional resets
soc: imx: gpcv2: add support for optional resets
dt-bindings: power: add defines for i.MX8MM power domains
soc: imx: gpcv2: add support for i.MX8MM power domains
soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
domains
It's nice to see this finally moving forward!
As you know, Hantro G2 support for i.MX8MQ (and i.MX8MP, i.MX8MM) is currently
blocked, as you have requested:
https://lore.kernel.org/driverdev-devel/5aa5700b862234895a7a6eb251ca3c80fdc1a6d3.camel@collabora.com/
So, I think we really need to include i.MX8MP and i.MX8MQ on this series.
It's been quite a while and we really need to have that. To be honest,
I fear that
if we merge this series as-is, MX8MP and MX8MP support will fall in
the oblivion,
and Hantro G2 VPU will remain unusable.
We are planning to submit Hantro G2 VP9 support soon, and we've been testing
on various platforms, but it will also be blocked by lack of power-domains.
In the future, please Cc the linux-media mailing list, as well as
Benjamin, Andrzej and myself, so we can follow this.
From: Benjamin Gaignard <benjamin.gaignard@collabora.com> Date: 2021-09-03 12:26:50
Le 09/08/2021 à 10:15, Lucas Stach a écrit :
Hi Ezequiel,
Am Mittwoch, dem 04.08.2021 um 11:30 -0300 schrieb Ezequiel Garcia:
quoted
Hi Peng, Lucas,
On Wed, 5 May 2021 at 21:32, Peng Fan (OSS) [off-list ref] wrote:
quoted
From: Peng Fan <peng.fan@nxp.com>
V2:
- Add R-b/A-b tag
- Merge V1 patch 13 to V2 patch 6
- Drop V1 patch 15
- Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
details
- Add explaination in patch 8 for "why the resets are not defined"
This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
minor changes from me to make it could work with i.MX BLK-CTL driver.
Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
all the patches, Jacky Bai on help debug issues.
Lucas Stach (12):
soc: imx: gpcv2: move to more ideomatic error handling in probe
soc: imx: gpcv2: move domain mapping to domain driver probe
soc: imx: gpcv2: switch to clk_bulk_* API
soc: imx: gpcv2: split power up and power down sequence control
soc: imx: gpcv2: wait for ADB400 handshake
soc: imx: gpcv2: add runtime PM support for power-domains
soc: imx: gpcv2: allow domains without power-sequence control
dt-bindings: imx: gpcv2: add support for optional resets
soc: imx: gpcv2: add support for optional resets
dt-bindings: power: add defines for i.MX8MM power domains
soc: imx: gpcv2: add support for i.MX8MM power domains
soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
domains
It's nice to see this finally moving forward!
As you know, Hantro G2 support for i.MX8MQ (and i.MX8MP, i.MX8MM) is currently
blocked, as you have requested:
https://lore.kernel.org/driverdev-devel/5aa5700b862234895a7a6eb251ca3c80fdc1a6d3.camel@collabora.com/
So, I think we really need to include i.MX8MP and i.MX8MQ on this series.
It's been quite a while and we really need to have that. To be honest,
I fear that
if we merge this series as-is, MX8MP and MX8MP support will fall in
the oblivion,
and Hantro G2 VPU will remain unusable.
We are planning to submit Hantro G2 VP9 support soon, and we've been testing
on various platforms, but it will also be blocked by lack of power-domains.
In the future, please Cc the linux-media mailing list, as well as
Benjamin, Andrzej and myself, so we can follow this.
Please take a look at [1], which is the current state of this work. I
intend to add both i.MX8MQ and i.MX8MP support to the series now, as it
seems that there have been no big objections to my approach over the
last 2 weeks, where I was on vacation. ;)
Hi Lucas,
I have tried to implement the block control driver for imx8mq.
I didn't manage to get it working.
My implementation is here:
https://gitlab.collabora.com/benjamin.gaignard/for-upstream/-/tree/IMX8MQ_BLK_CTRL
While you have the same in IMX8MM do you have also made changes in Hantro driver ?
If it is that can you share these changes ? I have include mine in the above branch.
Regards,
Benjamin