This series:
1. Adds CPU/core voltage bump before system is rebooted.
2. Adds new devm_tegra_core_dev_init_opp_table() helper and switches
Tegra memory drivers to use it.
3. Adds compile-testing support to the Tegra memory drivers.
4. Adds Tegra SoC core power domain support.
Changelog:
v6: - Fixed another compile-test trouble reported for v5. I double checked
the clk stubs this time and compiled them locally.
- Moved the Kconfig properties required for the core power domain
to the PMC Kconfig entry. This was suggested by Thierry Reding.
v5: - Fixed compile-test warning reported for v3 which happened due to
copy-paste typo around new tegra210_clk_emc_attach() stub.
v4: - Fixed misplaced prototypes of tegra_pmc_core_domain_state_synced(),
which I noticed only after sending out v3. This fixes building with
!CONFIG_PM_SLEEP.
v3: - Dropped "Detach coupled regulator before coupling count is dropped"
patch that was added in v2 since it missed regulator locking and
it should be more reasonable to add a new generic hook for syncing
before detaching. For now it's optional to sync Tegra SoC regulators
before detaching since it's not something that happens in practice,
hence it's more optimal to simply drop that feature.
- Added more stubs for T210 clk driver which should fix compile-testing
problem reported for v2 by kernel robot.
- Added COMMON_CLK for COMPILE_TEST of memory drivers since for
today the problem of compile-testing of legacy platforms that use
HAVE_LEGACY_CLK isn't solved, we will be able to remove it after
fixing the legacy platforms.
- Factored out new PMC driver state syncing feature into a separate
patch "pmc: Add driver state syncing", which was requested by
Ulf Hansson in a review comment to v2.
- Added r-b from Ulf Hansson to the PMC binding-update patch that he
gave to v2.
v2: - Added more clk stubs that should fix build error reported by the
kernel bot to v1 for the T210 memory driver.
- Added r-b from Krzysztof Kozlowski to the memory patches.
- Added back voltage restore on detaching of coupled regulators to
the T20 regulator coupler which previously got missed by accident.
- Added new patch:
regulator: core: Detach coupled regulator before coupling count is dropped
It fixes skipped voltage balancing on detaching of regulators which I
happened to notice due to the recent regression of the MAX77620 driver
that made driver to re-probe and detach coupled regulators.
v1: - Merged previous patches into this single series.
- Added ack from Rob Herring to the core domain DT binding patch.
- Implemented suggestions that were given by Krzysztof Kozlowski:
- Factored out soc_is_tegra() stub into standalone patch.
- Updated tags of the "Fix compilation warnings on 64bit platforms"
patch, added reported-by from lkp robot and removed suggested-by
from Nathan Chancellor.
- Switched to use use BIT() macro.
- Added r-b from Krzysztof Kozlowski to "Enable compile testing for
all drivers" patch.
- Added r-b from Nathan Chancellor.
- Dropped voltage floor/ceiling from devm_tegra_core_dev_init_opp_table()
since only memory drivers now need to initialize voltage vote and they
don't need floor/ceil. This was suggested by Viresh Kumar.
Dmitry Osipenko (14):
regulator: core: Add regulator_sync_voltage_rdev()
soc/tegra: regulators: Bump voltages on system reboot
soc/tegra: Add stub for soc_is_tegra()
soc/tegra: Add devm_tegra_core_dev_init_opp_table()
soc/tegra: fuse: Add stubs needed for compile-testing
clk: tegra: Add stubs needed for compile-testing
memory: tegra: Fix compilation warnings on 64bit platforms
memory: tegra: Enable compile testing for all drivers
memory: tegra20-emc: Use devm_tegra_core_dev_init_opp_table()
memory: tegra30-emc: Use devm_tegra_core_dev_init_opp_table()
dt-bindings: soc: tegra-pmc: Document core power domain
soc/tegra: pmc: Add core power domain
soc/tegra: pmc: Add driver state syncing
soc/tegra: regulators: Support core domain state syncing
.../arm/tegra/nvidia,tegra20-pmc.yaml | 35 +++++
drivers/memory/tegra/Kconfig | 16 +-
drivers/memory/tegra/tegra124-emc.c | 4 +-
drivers/memory/tegra/tegra20-emc.c | 48 +-----
drivers/memory/tegra/tegra30-emc.c | 52 +-----
drivers/regulator/core.c | 23 +++
drivers/soc/tegra/Kconfig | 2 +
drivers/soc/tegra/common.c | 97 ++++++++++++
drivers/soc/tegra/pmc.c | 148 +++++++++++++++++-
drivers/soc/tegra/regulators-tegra20.c | 94 ++++++++++-
drivers/soc/tegra/regulators-tegra30.c | 93 ++++++++++-
include/linux/clk/tegra.h | 100 +++++++++---
include/linux/regulator/driver.h | 1 +
include/soc/tegra/common.h | 31 ++++
include/soc/tegra/fuse.h | 20 ++-
include/soc/tegra/pmc.h | 7 +
16 files changed, 640 insertions(+), 131 deletions(-)
--
2.30.2
Some NVIDIA Tegra devices use a CPU soft-reset method for the reboot and
in this case we need to restore the coupled voltages to the state that is
suitable for hardware during boot. Add new regulator_sync_voltage_rdev()
helper which is needed by regulator drivers in order to sync voltage of
a coupled regulators.
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/regulator/core.c | 23 +++++++++++++++++++++++
include/linux/regulator/driver.h | 1 +
2 files changed, 24 insertions(+)
@@ -4111,6 +4111,29 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,}EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);+intregulator_sync_voltage_rdev(structregulator_dev*rdev)+{+intret;++regulator_lock(rdev);++if(!rdev->desc->ops->set_voltage&&+!rdev->desc->ops->set_voltage_sel){+ret=-EINVAL;+gotoout;+}++/* balance only, if regulator is coupled */+if(rdev->coupling_desc.n_coupled>1)+ret=regulator_balance_voltage(rdev,PM_SUSPEND_ON);+else+ret=-EOPNOTSUPP;++out:+regulator_unlock(rdev);+returnret;+}+/***regulator_sync_voltage-re-applylastregulatoroutputvoltage*@regulator:regulatorsource
Ensure that SoC voltages are at a level suitable for a system reboot.
This is important for some devices that use CPU reset method for the
rebooting. SoC CPU and core voltages now are be restored to a level
that is suitable for rebooting. This patch fixes hang on reboot on
Asus Transformer TF101, it was also reported as fixing some of reboot
issues on Toshiba AC100.
Reported-by: Nikola Milosavljević <redacted>
Tested-by: Nikola Milosavljević <redacted> # TF101
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/soc/tegra/regulators-tegra20.c | 75 +++++++++++++++++++++++++-
drivers/soc/tegra/regulators-tegra30.c | 75 +++++++++++++++++++++++++-
2 files changed, 148 insertions(+), 2 deletions(-)
@@ -242,6 +246,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,if(cpu_uV<0)returncpu_uV;+/* store boot voltage level */+if(!tegra->cpu_min_uV)+tegra->cpu_min_uV=cpu_uV;+/**CPU'sregulatormaynothaveanyconsumers,hencethevoltage*mustnotbechangedinthatcasebecauseCPUsimplywon't
@@ -250,6 +258,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,if(!cpu_min_uV_consumers)cpu_min_uV=cpu_uV;+/* restore boot voltage level */+if(tegra->sys_reboot_mode)+cpu_min_uV=max(cpu_min_uV,tegra->cpu_min_uV);+if(cpu_min_uV>cpu_uV){err=tegra20_core_rtc_update(tegra,core_rdev,rtc_rdev,cpu_uV,cpu_min_uV);
@@ -290,6 +302,8 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,return-EINVAL;}+tegra->sys_reboot_mode=READ_ONCE(tegra->sys_reboot_mode_req);+if(rdev==cpu_rdev)returntegra20_cpu_voltage_update(tegra,cpu_rdev,core_rdev,rtc_rdev);
@@ -303,6 +317,51 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,return-EPERM;}+staticinttegra20_regulator_prepare_reboot(structtegra_regulator_coupler*tegra,+boolsys_reboot_mode)+{+interr;++if(!tegra->core_rdev||!tegra->rtc_rdev||!tegra->cpu_rdev)+return0;++WRITE_ONCE(tegra->sys_reboot_mode_req,true);++/*+*SomedevicesuseCPUsoft-rebootmethodandinthiscasewe+*shouldensurethatvoltagesaresanefortherebootbyrestoring+*theminimumbootlevels.+*/+err=regulator_sync_voltage_rdev(tegra->cpu_rdev);+if(err)+returnerr;++err=regulator_sync_voltage_rdev(tegra->core_rdev);+if(err)+returnerr;++WRITE_ONCE(tegra->sys_reboot_mode_req,sys_reboot_mode);++return0;+}++staticinttegra20_regulator_reboot(structnotifier_block*notifier,+unsignedlongevent,void*cmd)+{+structtegra_regulator_coupler*tegra;+intret;++if(event!=SYS_RESTART)+returnNOTIFY_DONE;++tegra=container_of(notifier,structtegra_regulator_coupler,+reboot_notifier);++ret=tegra20_regulator_prepare_reboot(tegra,true);++returnnotifier_from_errno(ret);+}+staticinttegra20_regulator_attach(structregulator_coupler*coupler,structregulator_dev*rdev){
@@ -335,6 +394,14 @@ static int tegra20_regulator_detach(struct regulator_coupler *coupler,{structtegra_regulator_coupler*tegra=to_tegra_coupler(coupler);+/*+*Wedon'texpectregulatorstobedecoupledduringreboot,+*thismayracewiththereboothandlerandshouldn'tever+*happeninpractice.+*/+if(WARN_ON_ONCE(system_state>SYSTEM_RUNNING))+return-EPERM;+if(tegra->core_rdev==rdev){tegra->core_rdev=NULL;return0;
@@ -172,6 +176,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,if(cpu_uV<0)returncpu_uV;+/* store boot voltage level */+if(!tegra->cpu_min_uV)+tegra->cpu_min_uV=cpu_uV;+/**CPU'sregulatormaynothaveanyconsumers,hencethevoltage*mustnotbechangedinthatcasebecauseCPUsimplywon't
@@ -195,6 +203,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,if(err)returnerr;+/* restore boot voltage level */+if(tegra->sys_reboot_mode)+cpu_min_uV=max(cpu_min_uV,tegra->cpu_min_uV);+if(core_min_limited_uV>core_uV){pr_err("core voltage constraint violated: %d %d %d\n",core_uV,core_min_limited_uV,cpu_uV);
@@ -263,9 +275,56 @@ static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,return-EINVAL;}+tegra->sys_reboot_mode=READ_ONCE(tegra->sys_reboot_mode_req);+returntegra30_voltage_update(tegra,cpu_rdev,core_rdev);}+staticinttegra30_regulator_prepare_reboot(structtegra_regulator_coupler*tegra,+boolsys_reboot_mode)+{+interr;++if(!tegra->core_rdev||!tegra->cpu_rdev)+return0;++WRITE_ONCE(tegra->sys_reboot_mode_req,true);++/*+*SomedevicesuseCPUsoft-rebootmethodandinthiscasewe+*shouldensurethatvoltagesaresanefortherebootbyrestoring+*theminimumbootlevels.+*/+err=regulator_sync_voltage_rdev(tegra->cpu_rdev);+if(err)+returnerr;++err=regulator_sync_voltage_rdev(tegra->core_rdev);+if(err)+returnerr;++WRITE_ONCE(tegra->sys_reboot_mode_req,sys_reboot_mode);++return0;+}++staticinttegra30_regulator_reboot(structnotifier_block*notifier,+unsignedlongevent,void*cmd)+{+structtegra_regulator_coupler*tegra;+intret;++if(event!=SYS_RESTART)+returnNOTIFY_DONE;++tegra=container_of(notifier,structtegra_regulator_coupler,+reboot_notifier);++ret=tegra30_regulator_prepare_reboot(tegra,true);++returnnotifier_from_errno(ret);+}+staticinttegra30_regulator_attach(structregulator_coupler*coupler,structregulator_dev*rdev){
@@ -292,6 +351,14 @@ static int tegra30_regulator_detach(struct regulator_coupler *coupler,{structtegra_regulator_coupler*tegra=to_tegra_coupler(coupler);+/*+*Wedon'texpectregulatorstobedecoupledduringreboot,+*thismayracewiththereboothandlerandshouldn'tever+*happeninpractice.+*/+if(WARN_ON_ONCE(system_state>SYSTEM_RUNNING))+return-EPERM;+if(tegra->core_rdev==rdev){tegra->core_rdev=NULL;return0;
@@ -31,3 +38,93 @@ bool soc_is_tegra(void)returnmatch!=NULL;}++staticinttegra_core_dev_init_opp_state(structdevice*dev)+{+unsignedlongrate;+structclk*clk;+interr;++clk=devm_clk_get(dev,NULL);+if(IS_ERR(clk)){+dev_err(dev,"failed to get clk: %pe\n",clk);+returnPTR_ERR(clk);+}++rate=clk_get_rate(clk);+if(!rate){+dev_err(dev,"failed to get clk rate\n");+return-EINVAL;+}++/* first dummy rate-setting initializes voltage vote */+err=dev_pm_opp_set_rate(dev,rate);+if(err){+dev_err(dev,"failed to initialize OPP clock: %d\n",err);+returnerr;+}++return0;+}++/**+*devm_tegra_core_dev_init_opp_table()-initializeOPPtable+*@dev:deviceforwhichOPPtableisinitialized+*@params:pointertotheOPPtableconfiguration+*+*ThisfunctionwillinitializeOPPtableandsyncOPPstateofaTegraSoC+*coredevice.+*+*Return:0onsuccessorerrorno.+*/+intdevm_tegra_core_dev_init_opp_table(structdevice*dev,+structtegra_core_opp_params*params)+{+u32hw_version;+interr;++err=devm_pm_opp_set_clkname(dev,NULL);+if(err){+dev_err(dev,"failed to set OPP clk: %d\n",err);+returnerr;+}++/* Tegra114+ doesn't support OPP yet */+if(!of_machine_is_compatible("nvidia,tegra20")&&+!of_machine_is_compatible("nvidia,tegra30"))+return-ENODEV;++if(of_machine_is_compatible("nvidia,tegra20"))+hw_version=BIT(tegra_sku_info.soc_process_id);+else+hw_version=BIT(tegra_sku_info.soc_speedo_id);++err=devm_pm_opp_set_supported_hw(dev,&hw_version,1);+if(err){+dev_err(dev,"failed to set OPP supported HW: %d\n",err);+returnerr;+}++/*+*Olderdevice-treeshaveanemptyOPPtable,wewillget+*-ENODEVfromdevm_pm_opp_of_add_table()inthiscase.+*/+err=devm_pm_opp_of_add_table(dev);+if(err){+if(err==-ENODEV)+dev_err_once(dev,"OPP table not found, please update device-tree\n");+else+dev_err(dev,"failed to add OPP table: %d\n",err);++returnerr;+}++if(params->init_state){+err=tegra_core_dev_init_opp_state(dev);+if(err)+returnerr;+}++return0;+}+EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);
@@ -144,17 +130,10 @@ typedef long (tegra20_clk_emc_round_cb)(unsigned long rate,unsignedlongmin_rate,unsignedlongmax_rate,void*arg);--voidtegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb*round_cb,-void*cb_arg);-inttegra20_clk_prepare_emc_mc_same_freq(structclk*emc_clk,boolsame);-typedefint(tegra124_emc_prepare_timing_change_cb)(structtegra_emc*emc,unsignedlongrate);typedefvoid(tegra124_emc_complete_timing_change_cb)(structtegra_emc*emc,unsignedlongrate);-voidtegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb*prep_cb,-tegra124_emc_complete_timing_change_cb*complete_cb);structtegra210_clk_emc_config{unsignedlongrate;
Fix compilation warning on 64bit platforms caused by implicit promotion
of 32bit signed integer to a 64bit unsigned value which happens after
enabling compile-testing of the EMC drivers.
Reported-by: kernel test robot <redacted>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Krzysztof Kozlowski <redacted>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/memory/tegra/tegra124-emc.c | 4 ++--
drivers/memory/tegra/tegra30-emc.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
@@ -908,49 +908,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)returnerr;}-staticinttegra_emc_opp_table_init(structtegra_emc*emc)-{-u32hw_version=BIT(tegra_sku_info.soc_process_id);-structopp_table*hw_opp_table;-interr;--hw_opp_table=dev_pm_opp_set_supported_hw(emc->dev,&hw_version,1);-err=PTR_ERR_OR_ZERO(hw_opp_table);-if(err){-dev_err(emc->dev,"failed to set OPP supported HW: %d\n",err);-returnerr;-}--err=dev_pm_opp_of_add_table(emc->dev);-if(err){-if(err==-ENODEV)-dev_err(emc->dev,"OPP table not found, please update your device tree\n");-else-dev_err(emc->dev,"failed to add OPP table: %d\n",err);--gotoput_hw_table;-}--dev_info_once(emc->dev,"OPP HW ver. 0x%x, current clock rate %lu MHz\n",-hw_version,clk_get_rate(emc->clk)/1000000);--/* first dummy rate-set initializes voltage state */-err=dev_pm_opp_set_rate(emc->dev,clk_get_rate(emc->clk));-if(err){-dev_err(emc->dev,"failed to initialize OPP clock: %d\n",err);-gotoremove_table;-}--return0;--remove_table:-dev_pm_opp_of_remove_table(emc->dev);-put_hw_table:-dev_pm_opp_put_supported_hw(hw_opp_table);--returnerr;-}-staticvoiddevm_tegra_emc_unset_callback(void*data){tegra20_clk_set_emc_round_callback(NULL,NULL);
@@ -1077,6 +1034,7 @@ static int tegra_emc_devfreq_init(struct tegra_emc *emc)staticinttegra_emc_probe(structplatform_device*pdev){+structtegra_core_opp_paramsopp_params={};structdevice_node*np;structtegra_emc*emc;intirq,err;
@@ -1122,7 +1080,9 @@ static int tegra_emc_probe(struct platform_device *pdev)if(err)returnerr;-err=tegra_emc_opp_table_init(emc);+opp_params.init_state=true;++err=devm_tegra_core_dev_init_opp_table(&pdev->dev,&opp_params);if(err)returnerr;
@@ -1480,49 +1480,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)returnerr;}-staticinttegra_emc_opp_table_init(structtegra_emc*emc)-{-u32hw_version=BIT(tegra_sku_info.soc_speedo_id);-structopp_table*hw_opp_table;-interr;--hw_opp_table=dev_pm_opp_set_supported_hw(emc->dev,&hw_version,1);-err=PTR_ERR_OR_ZERO(hw_opp_table);-if(err){-dev_err(emc->dev,"failed to set OPP supported HW: %d\n",err);-returnerr;-}--err=dev_pm_opp_of_add_table(emc->dev);-if(err){-if(err==-ENODEV)-dev_err(emc->dev,"OPP table not found, please update your device tree\n");-else-dev_err(emc->dev,"failed to add OPP table: %d\n",err);--gotoput_hw_table;-}--dev_info_once(emc->dev,"OPP HW ver. 0x%x, current clock rate %lu MHz\n",-hw_version,clk_get_rate(emc->clk)/1000000);--/* first dummy rate-set initializes voltage state */-err=dev_pm_opp_set_rate(emc->dev,clk_get_rate(emc->clk));-if(err){-dev_err(emc->dev,"failed to initialize OPP clock: %d\n",err);-gotoremove_table;-}--return0;--remove_table:-dev_pm_opp_of_remove_table(emc->dev);-put_hw_table:-dev_pm_opp_put_supported_hw(hw_opp_table);--returnerr;-}-staticvoiddevm_tegra_emc_unset_callback(void*data){tegra20_clk_set_emc_round_callback(NULL,NULL);
@@ -1568,6 +1525,7 @@ static int tegra_emc_init_clk(struct tegra_emc *emc)staticinttegra_emc_probe(structplatform_device*pdev){+structtegra_core_opp_paramsopp_params={};structdevice_node*np;structtegra_emc*emc;interr;
@@ -1617,7 +1575,9 @@ static int tegra_emc_probe(struct platform_device *pdev)if(err)returnerr;-err=tegra_emc_opp_table_init(emc);+opp_params.init_state=true;++err=devm_tegra_core_dev_init_opp_table(&pdev->dev,&opp_params);if(err)returnerr;
NVIDIA Tegra SoCs have multiple power domains, each domain corresponds
to an external SoC power rail. Core power domain covers vast majority of
hardware blocks within a Tegra SoC. The voltage of a power domain should
be set to a level which satisfies all devices within the power domain.
Add support for the core power domain which controls voltage state of the
domain. This allows us to support system-wide DVFS on Tegra20-210 SoCs.
The PMC powergate domains now are sub-domains of the core domain, this
requires device-tree updating, older DTBs are unaffected and will continue
to work as before.
Tested-by: Peter Geis <redacted> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <redacted> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <redacted> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/soc/tegra/Kconfig | 2 +
drivers/soc/tegra/pmc.c | 120 ++++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+)
@@ -1297,12 +1298,110 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)returnerr;}+staticint+tegra_pmc_core_pd_set_performance_state(structgeneric_pm_domain*genpd,+unsignedintlevel)+{+structdev_pm_opp*opp;+interr;++opp=dev_pm_opp_find_level_ceil(&genpd->dev,&level);+if(IS_ERR(opp)){+dev_err(&genpd->dev,"failed to find OPP for level %u: %pe\n",+level,opp);+returnPTR_ERR(opp);+}++mutex_lock(&pmc->powergates_lock);+err=dev_pm_opp_set_opp(pmc->dev,opp);+mutex_unlock(&pmc->powergates_lock);++dev_pm_opp_put(opp);++if(err){+dev_err(&genpd->dev,"failed to set voltage to %duV: %d\n",+level,err);+returnerr;+}++return0;+}++staticunsignedint+tegra_pmc_core_pd_opp_to_performance_state(structgeneric_pm_domain*genpd,+structdev_pm_opp*opp)+{+returndev_pm_opp_get_level(opp);+}++staticinttegra_pmc_core_pd_add(structtegra_pmc*pmc,structdevice_node*np)+{+staticstructlock_class_keytegra_core_domain_lock_class;+structgeneric_pm_domain*genpd;+constchar*rname="core";+interr;++genpd=devm_kzalloc(pmc->dev,sizeof(*genpd),GFP_KERNEL);+if(!genpd)+return-ENOMEM;++genpd->name=np->name;+genpd->set_performance_state=tegra_pmc_core_pd_set_performance_state;+genpd->opp_to_performance_state=tegra_pmc_core_pd_opp_to_performance_state;++err=devm_pm_opp_set_regulators(pmc->dev,&rname,1);+if(err)+returndev_err_probe(pmc->dev,err,+"failed to set core OPP regulator\n");++err=pm_genpd_init(genpd,NULL,false);+if(err){+dev_err(pmc->dev,"failed to init core genpd: %d\n",err);+returnerr;+}++/*+*Wehavea"PMC pwrgate -> Core"hierarchyofthepowerdomains+*wherePMCneedstoresumeandchangeperformance(voltage)ofthe+*CoredomainfromthePMCGENPDon/offcallbacks,henceweneed+*toannotatethelockinordertoremoveconfusionfromthe+*lockdepcheckerwhenanestedaccesshappens.+*/+lockdep_set_class(&genpd->mlock,&tegra_core_domain_lock_class);++err=of_genpd_add_provider_simple(np,genpd);+if(err){+dev_err(pmc->dev,"failed to add core genpd: %d\n",err);+gotoremove_genpd;+}++return0;++remove_genpd:+pm_genpd_remove(genpd);++returnerr;+}+staticinttegra_powergate_init(structtegra_pmc*pmc,structdevice_node*parent){+structof_phandle_argschild_args,parent_args;structdevice_node*np,*child;interr=0;+/*+*Corepowerdomainistheparentofpowergatedomains,henceit+*shouldberegisteredfirst.+*/+np=of_get_child_by_name(parent,"core-domain");+if(np){+err=tegra_pmc_core_pd_add(pmc,np);+of_node_put(np);+if(err)+returnerr;+}+np=of_get_child_by_name(parent,"powergates");if(!np)return0;
@@ -1313,6 +1412,21 @@ static int tegra_powergate_init(struct tegra_pmc *pmc,of_node_put(child);break;}++if(of_parse_phandle_with_args(child,"power-domains",+"#power-domain-cells",+0,&parent_args))+continue;++child_args.np=child;+child_args.args_count=0;++err=of_genpd_add_subdomain(&parent_args,&child_args);+of_node_put(parent_args.np);+if(err){+of_node_put(child);+break;+}}of_node_put(np);
All NVIDIA Tegra SoCs have a core power domain where majority of hardware
blocks reside. Document the new core power domain properties.
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Ulf Hansson <redacted>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
.../arm/tegra/nvidia,tegra20-pmc.yaml | 35 +++++++++++++++++++
1 file changed, 35 insertions(+)
@@ -301,6 +301,33 @@ patternProperties:additionalProperties:false+core-domain:+type:object+description:|+The vast majority of hardware blocks of Tegra SoC belong to a+Core power domain, which has a dedicated voltage rail that powers+the blocks.++properties:+operating-points-v2:+description:+Should contain level, voltages and opp-supported-hw property.+The supported-hw is a bitfield indicating SoC speedo or process+ID mask.++"#power-domain-cells":+const:0++required:+-operating-points-v2+-"#power-domain-cells"++additionalProperties:false++core-supply:+description:+Phandle to voltage regulator connected to the SoC Core power rail.+required:-compatible-reg
Add driver state syncing that is invoked once all PMC consumers are
attached and ready. The consumers are the power domain clients.
The synchronization callback is invoked once all client drivers are
probed, the driver core handles this for us. This callback informs
PMC driver that all voltage votes are initialized by each PD client
and it's safe to begin voltage scaling of the core power domain.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/soc/tegra/pmc.c | 23 +++++++++++++++++++++++
include/soc/tegra/pmc.h | 7 +++++++
2 files changed, 30 insertions(+)
@@ -3787,6 +3794,21 @@ static const struct of_device_id tegra_pmc_match[] = {{}};+staticvoidtegra_pmc_sync_state(structdevice*dev)+{+interr;++pmc->core_domain_state_synced=true;++/* this is a no-op if core regulator isn't used */+mutex_lock(&pmc->powergates_lock);+err=dev_pm_opp_sync_regulators(dev);+mutex_unlock(&pmc->powergates_lock);++if(err)+dev_err(dev,"failed to sync regulators: %d\n",err);+}+staticstructplatform_drivertegra_pmc_driver={.driver={.name="tegra-pmc",
@@ -171,6 +171,8 @@ int tegra_io_rail_power_off(unsigned int id);voidtegra_pmc_set_suspend_mode(enumtegra_suspend_modemode);voidtegra_pmc_enter_suspend_mode(enumtegra_suspend_modemode);+booltegra_pmc_core_domain_state_synced(void);+#elsestaticinlineinttegra_powergate_power_on(unsignedintid){
The core voltage shall not drop until state of core domain is synced,
i.e. all device drivers that use core domain are loaded and ready.
Support core domain state syncing. The core domain driver invokes the
core-regulator voltage syncing once the state of domain is synced, at
this point the core voltage is allowed to go lower than the level left
after bootloader.
Tested-by: Peter Geis <redacted> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <redacted> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <redacted> # Ouya T30
Reviewed-by: Ulf Hansson <redacted>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/soc/tegra/regulators-tegra20.c | 19 ++++++++++++++++++-
drivers/soc/tegra/regulators-tegra30.c | 18 +++++++++++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
@@ -42,6 +44,21 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,intcore_cur_uV;interr;+/*+*Tegra20SoChascriticalDVFS-capabledevicesthatare+*permanently-activeoractiveataboottime,likeEMC+*(DRAMcontroller)orDisplaycontrollerforexample.+*+*ThevoltageofaCORESoCpowerdomainshallnotbedroppedbelow+*aminimumlevel,whichisdeterminedbydevice'sclockrate.+*Thismeansthatwecan'tfullyallowCOREvoltagescalinguntil+*thestateofallDVFS-criticalCOREdevicesissynced.+*/+if(tegra_pmc_core_domain_state_synced()&&!tegra->sys_reboot_mode){+pr_info_once("voltage state synced\n");+return0;+}+if(tegra->core_min_uV>0)returntegra->core_min_uV;
@@ -62,7 +79,7 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,*/tegra->core_min_uV=core_max_uV;-pr_info("core minimum voltage limited to %duV\n",tegra->core_min_uV);+pr_info("core voltage initialized to %duV\n",tegra->core_min_uV);returntegra->core_min_uV;}
@@ -43,6 +44,21 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,intcore_cur_uV;interr;+/*+*Tegra30SoChascriticalDVFS-capabledevicesthatare+*permanently-activeoractiveataboottime,likeEMC+*(DRAMcontroller)orDisplaycontrollerforexample.+*+*ThevoltageofaCORESoCpowerdomainshallnotbedroppedbelow+*aminimumlevel,whichisdeterminedbydevice'sclockrate.+*Thismeansthatwecan'tfullyallowCOREvoltagescalinguntil+*thestateofallDVFS-criticalCOREdevicesissynced.+*/+if(tegra_pmc_core_domain_state_synced()&&!tegra->sys_reboot_mode){+pr_info_once("voltage state synced\n");+return0;+}+if(tegra->core_min_uV>0)returntegra->core_min_uV;
@@ -63,7 +79,7 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,*/tegra->core_min_uV=core_max_uV;-pr_info("core minimum voltage limited to %duV\n",tegra->core_min_uV);+pr_info("core voltage initialized to %duV\n",tegra->core_min_uV);returntegra->core_min_uV;}
On Tue, Jun 01, 2021 at 05:31:05AM +0300, Dmitry Osipenko wrote:
This series:
1. Adds CPU/core voltage bump before system is rebooted.
2. Adds new devm_tegra_core_dev_init_opp_table() helper and switches
Tegra memory drivers to use it.
3. Adds compile-testing support to the Tegra memory drivers.
4. Adds Tegra SoC core power domain support.
Changelog:
v6: - Fixed another compile-test trouble reported for v5. I double checked
the clk stubs this time and compiled them locally.
Heh... I just fixed those locally on top of your v5. Let me see if I can
roll back the changes and apply this new set instead.
Thierry
On Tue, Jun 01, 2021 at 05:31:05AM +0300, Dmitry Osipenko wrote:
quoted
This series:
1. Adds CPU/core voltage bump before system is rebooted.
2. Adds new devm_tegra_core_dev_init_opp_table() helper and switches
Tegra memory drivers to use it.
3. Adds compile-testing support to the Tegra memory drivers.
4. Adds Tegra SoC core power domain support.
Changelog:
v6: - Fixed another compile-test trouble reported for v5. I double checked
the clk stubs this time and compiled them locally.
Heh... I just fixed those locally on top of your v5. Let me see if I can
roll back the changes and apply this new set instead.
Thank you! You probably saw already that Ulf Hansson suggested to remove
the lockdep annotation for now from the core PD, I'll make a v7 with
this small change.
On Tue, Jun 01, 2021 at 06:51:33PM +0300, Dmitry Osipenko wrote:
01.06.2021 14:27, Thierry Reding пишет:
quoted
On Tue, Jun 01, 2021 at 05:31:05AM +0300, Dmitry Osipenko wrote:
quoted
This series:
1. Adds CPU/core voltage bump before system is rebooted.
2. Adds new devm_tegra_core_dev_init_opp_table() helper and switches
Tegra memory drivers to use it.
3. Adds compile-testing support to the Tegra memory drivers.
4. Adds Tegra SoC core power domain support.
Changelog:
v6: - Fixed another compile-test trouble reported for v5. I double checked
the clk stubs this time and compiled them locally.
Heh... I just fixed those locally on top of your v5. Let me see if I can
roll back the changes and apply this new set instead.
Thank you! You probably saw already that Ulf Hansson suggested to remove
the lockdep annotation for now from the core PD, I'll make a v7 with
this small change.
Can you perhaps post this change as a follow-up? That way I can just
merge it into the corresponding branch, which may be easier than backing
out all the changes spread over four branches and applying basically the
same thing again.
Thierry
On Tue, Jun 01, 2021 at 06:51:33PM +0300, Dmitry Osipenko wrote:
quoted
01.06.2021 14:27, Thierry Reding пишет:
quoted
On Tue, Jun 01, 2021 at 05:31:05AM +0300, Dmitry Osipenko wrote:
quoted
This series:
1. Adds CPU/core voltage bump before system is rebooted.
2. Adds new devm_tegra_core_dev_init_opp_table() helper and switches
Tegra memory drivers to use it.
3. Adds compile-testing support to the Tegra memory drivers.
4. Adds Tegra SoC core power domain support.
Changelog:
v6: - Fixed another compile-test trouble reported for v5. I double checked
the clk stubs this time and compiled them locally.
Heh... I just fixed those locally on top of your v5. Let me see if I can
roll back the changes and apply this new set instead.
Thank you! You probably saw already that Ulf Hansson suggested to remove
the lockdep annotation for now from the core PD, I'll make a v7 with
this small change.
Can you perhaps post this change as a follow-up? That way I can just
merge it into the corresponding branch, which may be easier than backing
out all the changes spread over four branches and applying basically the
same thing again.
On Mon, Jun 07, 2021 at 08:01:28AM +0200, Krzysztof Kozlowski wrote:
On 01/06/2021 04:31, Dmitry Osipenko wrote:
quoted
Enable compile testing for all Tegra memory drivers.
Reviewed-by: Krzysztof Kozlowski <redacted>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/memory/tegra/Kconfig | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
Hi Dmitry,
This fails on x86_64 and i386:
https://krzk.eu/#/builders/38/builds/260https://krzk.eu/#/builders/40/builds/261
/bin/ld: warning: orphan section `__reservedmem_of_table' from `drivers/memory/tegra/tegra210-emc-table.o' being placed in section `__reservedmem_of_table'
/bin/ld: drivers/memory/tegra/mc.o: in function `tegra_mc_probe':
mc.c:(.text+0x87a): undefined reference to `reset_controller_register'
make[1]: *** [/home/buildbot/worker/builddir/build/Makefile:1191: vmlinux] Error 1
It's a defconfig with:
scripts/config --file out/.config -e COMPILE_TEST -e OF -e SRAM -e
MEMORY -e PM_DEVFREQ -e ARM_PL172_MPMC -e ATMEL_SDRAMC -e ATMEL_EBI -e
BRCMSTB_DPFE -e BT1_L2_CTL -e TI_AEMIF -e TI_EMIF -e OMAP_GPMC -e
TI_EMIF_SRAM -e MVEBU_DEVBUS -e FSL_CORENET_CF -e FSL_IFC -e JZ4780_NEMC
-e MTK_SMI -e DA8XX_DDRCTL -e PL353_SMC -e RENESAS_RPCIF -e
STM32_FMC2_EBI -e SAMSUNG_MC -e EXYNOS5422_DMC -e EXYNOS_SROM -e
TEGRA_MC -e TEGRA20_EMC -e TEGRA30_EMC -e TEGRA124_EMC -e
TEGRA210_EMC_TABLE -e TEGRA210_EMC
Ugh... that's exactly one of the reasons why I dislike COMPILE_TEST...
though admittedly it does point out a missing dependency here. I think
we need to add && RESET_CONTROLLER to that || branch of the depends on
to fix that. ARCH_TEGRA selects RESET_CONTROLLER explicitly, so the
COMPILE_TEST branch needs to mirror that.
Either that, or I suppose we could add the depends on RESET_CONTROLLER
explicitly to TEGRA_MC, or perhaps even select it (although that could
cause conflicts down the road, but should be fine right now because
RESET_CONTROLLER doesn't have any other dependencies right now).
Not sure what to do about that orphaned __reservedmem_of_table section.
Maybe all we need to do is to select OF_RESERVED_MEM from
TEGRA210_EMC_TABLE?
Let me to a few test builds.
Thierry
On Mon, Jun 07, 2021 at 08:01:28AM +0200, Krzysztof Kozlowski wrote:
quoted
On 01/06/2021 04:31, Dmitry Osipenko wrote:
quoted
Enable compile testing for all Tegra memory drivers.
Reviewed-by: Krzysztof Kozlowski <redacted>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/memory/tegra/Kconfig | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
Hi Dmitry,
This fails on x86_64 and i386:
https://krzk.eu/#/builders/38/builds/260https://krzk.eu/#/builders/40/builds/261
/bin/ld: warning: orphan section `__reservedmem_of_table' from `drivers/memory/tegra/tegra210-emc-table.o' being placed in section `__reservedmem_of_table'
/bin/ld: drivers/memory/tegra/mc.o: in function `tegra_mc_probe':
mc.c:(.text+0x87a): undefined reference to `reset_controller_register'
make[1]: *** [/home/buildbot/worker/builddir/build/Makefile:1191: vmlinux] Error 1
It's a defconfig with:
scripts/config --file out/.config -e COMPILE_TEST -e OF -e SRAM -e
MEMORY -e PM_DEVFREQ -e ARM_PL172_MPMC -e ATMEL_SDRAMC -e ATMEL_EBI -e
BRCMSTB_DPFE -e BT1_L2_CTL -e TI_AEMIF -e TI_EMIF -e OMAP_GPMC -e
TI_EMIF_SRAM -e MVEBU_DEVBUS -e FSL_CORENET_CF -e FSL_IFC -e JZ4780_NEMC
-e MTK_SMI -e DA8XX_DDRCTL -e PL353_SMC -e RENESAS_RPCIF -e
STM32_FMC2_EBI -e SAMSUNG_MC -e EXYNOS5422_DMC -e EXYNOS_SROM -e
TEGRA_MC -e TEGRA20_EMC -e TEGRA30_EMC -e TEGRA124_EMC -e
TEGRA210_EMC_TABLE -e TEGRA210_EMC
Ugh... that's exactly one of the reasons why I dislike COMPILE_TEST...
though admittedly it does point out a missing dependency here. I think
we need to add && RESET_CONTROLLER to that || branch of the depends on
to fix that. ARCH_TEGRA selects RESET_CONTROLLER explicitly, so the
COMPILE_TEST branch needs to mirror that.
Either that, or I suppose we could add the depends on RESET_CONTROLLER
explicitly to TEGRA_MC, or perhaps even select it (although that could
cause conflicts down the road, but should be fine right now because
RESET_CONTROLLER doesn't have any other dependencies right now).
The select will work.
The other option is to add stubs for the reset controller API.
/bin/ld: warning: orphan section `__reservedmem_of_table' from `drivers/memory/tegra/tegra210-emc-table.o' being placed in section `__reservedmem_of_table'
/bin/ld: drivers/memory/tegra/mc.o: in function `tegra_mc_probe':
mc.c:(.text+0x87a): undefined reference to `reset_controller_register'
make[1]: *** [/home/buildbot/worker/builddir/build/Makefile:1191: vmlinux] Error 1
...
Not sure what to do about that orphaned __reservedmem_of_table section.
Maybe all we need to do is to select OF_RESERVED_MEM from
TEGRA210_EMC_TABLE?
Select won't work easily, but the dependency for TEGRA210_EMC should.
On Mon, Jun 07, 2021 at 05:01:02PM +0300, Dmitry Osipenko wrote:
07.06.2021 16:36, Thierry Reding пишет:
quoted
quoted
/bin/ld: warning: orphan section `__reservedmem_of_table' from `drivers/memory/tegra/tegra210-emc-table.o' being placed in section `__reservedmem_of_table'
/bin/ld: drivers/memory/tegra/mc.o: in function `tegra_mc_probe':
mc.c:(.text+0x87a): undefined reference to `reset_controller_register'
make[1]: *** [/home/buildbot/worker/builddir/build/Makefile:1191: vmlinux] Error 1
...
quoted
Not sure what to do about that orphaned __reservedmem_of_table section.
Maybe all we need to do is to select OF_RESERVED_MEM from
TEGRA210_EMC_TABLE?
Select won't work easily, but the dependency for TEGRA210_EMC should.
Select works if I also select OF_EARLY_FLATTREE. That's slightly odd
because typically that's something that the platform would select, but
there's precedent for doing this in drivers/clk/x86/Kconfig, so I think
it'd be fine.
The attached patch resolves both of the above issues for me.
Krzysztof: do you want to squash that into the problematic patch or do
you want me to send this as a follow-up patch for you to apply? I guess
the latter since you've already sent out the PR for Will and ARM SoC?
Thierry
From: Krzysztof Kozlowski <hidden> Date: 2021-06-07 14:42:47
On 07/06/2021 16:19, Thierry Reding wrote:
On Mon, Jun 07, 2021 at 05:01:02PM +0300, Dmitry Osipenko wrote:
quoted
07.06.2021 16:36, Thierry Reding пишет:
quoted
quoted
/bin/ld: warning: orphan section `__reservedmem_of_table' from `drivers/memory/tegra/tegra210-emc-table.o' being placed in section `__reservedmem_of_table'
/bin/ld: drivers/memory/tegra/mc.o: in function `tegra_mc_probe':
mc.c:(.text+0x87a): undefined reference to `reset_controller_register'
make[1]: *** [/home/buildbot/worker/builddir/build/Makefile:1191: vmlinux] Error 1
...
quoted
Not sure what to do about that orphaned __reservedmem_of_table section.
Maybe all we need to do is to select OF_RESERVED_MEM from
TEGRA210_EMC_TABLE?
Select won't work easily, but the dependency for TEGRA210_EMC should.
Select works if I also select OF_EARLY_FLATTREE. That's slightly odd
because typically that's something that the platform would select, but
there's precedent for doing this in drivers/clk/x86/Kconfig, so I think
it'd be fine.
The attached patch resolves both of the above issues for me.
Krzysztof: do you want to squash that into the problematic patch or do
you want me to send this as a follow-up patch for you to apply? I guess
the latter since you've already sent out the PR for Will and ARM SoC?
Follow up, please, but I am not sure about selecting reset controller.
From the tegra/mc.c code I see it can be optional - if "reset_ops" is
provided. Therefore I think:
1. Reset controller should provide proper stubs. This will fix building
of mc.c when reset controller is not chosen (regardless of point #2 below).
2. Specific drivers should depend on it. Selecting user-visible symbols
is rather discourage because might lead to circular dependencies.
Best regards,
Krzysztof
On Mon, Jun 07, 2021 at 05:01:02PM +0300, Dmitry Osipenko wrote:
quoted
07.06.2021 16:36, Thierry Reding пишет:
quoted
quoted
/bin/ld: warning: orphan section `__reservedmem_of_table' from `drivers/memory/tegra/tegra210-emc-table.o' being placed in section `__reservedmem_of_table'
/bin/ld: drivers/memory/tegra/mc.o: in function `tegra_mc_probe':
mc.c:(.text+0x87a): undefined reference to `reset_controller_register'
make[1]: *** [/home/buildbot/worker/builddir/build/Makefile:1191: vmlinux] Error 1
...
quoted
Not sure what to do about that orphaned __reservedmem_of_table section.
Maybe all we need to do is to select OF_RESERVED_MEM from
TEGRA210_EMC_TABLE?
Select won't work easily, but the dependency for TEGRA210_EMC should.
Select works if I also select OF_EARLY_FLATTREE. That's slightly odd
because typically that's something that the platform would select, but
there's precedent for doing this in drivers/clk/x86/Kconfig, so I think
it'd be fine.
The attached patch resolves both of the above issues for me.
Krzysztof: do you want to squash that into the problematic patch or do
you want me to send this as a follow-up patch for you to apply? I guess
the latter since you've already sent out the PR for Will and ARM SoC?
Follow up, please, but I am not sure about selecting reset controller.
From the tegra/mc.c code I see it can be optional - if "reset_ops" is
provided. Therefore I think:
1. Reset controller should provide proper stubs. This will fix building
of mc.c when reset controller is not chosen (regardless of point #2 below).
2. Specific drivers should depend on it. Selecting user-visible symbols
is rather discourage because might lead to circular dependencies.
Thierry, should I send the patches or you're willing to do it?