Skip to content

Commit

Permalink
Merge tag 'omap-for-v5.11/genpd-drivers-signed' of git://git.kernel.o…
Browse files Browse the repository at this point in the history
…rg/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/omap-genpd

Driver changes for omaps for genpd for v5.11 merge window

This series of changes allows booting am335x with genpd and
device tree data without the legacy platform data. Also at
least am437x can be booted with gendp with power domain and
dts data. The SoC specific dts changes will be a separate
pull request.

We need the following driver changes merged before the dts
changes can be done:

- platform code needs a few improvments to probe l4_wkup first
  for clocks, and to bail out when there is no platform data

- ti-sysc driver needs a non-urgent fix for asserting rstctrl
  reset only after disabling the clocks, to probe modules with
  no known control registers, and added quirk handling for gpmc
  devices

- omap-prm driver needs a non-urgent fix for reset status bit,
  support added for pm_clk, and then we add the rest of am335x
  power domain data

- clock driver for am335x needs to keep l3_main clock enabled
  with genpd for suspend and resume to work

- wkup_m3 remoteproc driver needs support added for reset
  control if available instead of the legacy pdata callbacks

- pm33xx driver needs PM runtime support added for genpd

The am335x specific driver changes for the clock, wkup_m3,
pm33xx and remoteproc drivers are quite trivial and have not
caused merge conflicts in Linux next. I did not get acks for
these changes except from Santosh but had already pushed out
the branch already at that point. So I've added the related
driver maintainers to Cc.

* tag 'omap-for-v5.11/genpd-drivers-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  remoteproc/wkup_m3: Use reset control driver if available
  soc: ti: pm33xx: Enable basic PM runtime support for genpd
  soc: ti: omap-prm: am3: add genpd support for remaining PRM instances
  soc: ti: omap-prm: Add pm_clk for genpd
  clk: ti: am33xx: Keep am3 l3 main clock always on for genpd
  bus: ti-sysc: Implement GPMC debug quirk to drop platform data
  bus: ti-sysc: Support modules without control registers
  ARM: OMAP2+: Probe PRCM first to probe l4_wkup with simple-pm-bus
  ARM: OMAP2+: Check for inited flag
  bus: ti-sysc: Assert reset only after disabling clocks
  soc: ti: omap-prm: Do not check rstst bit on deassert if already deasserted
  bus: ti-sysc: Fix bogus resetdone warning on enable for cpsw
  bus: ti-sysc: Fix reset status check for modules with quirks
  ARM: OMAP2+: Fix missing select PM_GENERIC_DOMAINS_OF
  ARM: OMAP2+: Fix location for select PM_GENERIC_DOMAINS

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
  • Loading branch information
Arnd Bergmann committed Dec 9, 2020
2 parents 3650b22 + 57df7e3 commit 80c2500
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 39 deletions.
3 changes: 2 additions & 1 deletion arch/arm/mach-omap2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ config ARCH_OMAP2
depends on ARCH_MULTI_V6
select ARCH_OMAP2PLUS
select CPU_V6
select PM_GENERIC_DOMAINS if PM
select SOC_HAS_OMAP2_SDRC

config ARCH_OMAP3
Expand Down Expand Up @@ -106,6 +105,8 @@ config ARCH_OMAP2PLUS
select OMAP_DM_TIMER
select OMAP_GPMC
select PINCTRL
select PM_GENERIC_DOMAINS if PM
select PM_GENERIC_DOMAINS_OF if PM
select RESET_CONTROLLER
select SOC_BUS
select TI_SYSC
Expand Down
6 changes: 6 additions & 0 deletions arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,9 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
{
struct clk_hw_omap *clk;

if (!oh)
return NULL;

if (oh->clkdm) {
return oh->clkdm;
} else if (oh->_clk) {
Expand Down Expand Up @@ -3677,6 +3680,9 @@ static void __init omap_hwmod_setup_earlycon_flags(void)
*/
static int __init omap_hwmod_setup_all(void)
{
if (!inited)
return 0;

_ensure_mpu_hwmod_is_setup(NULL);

omap_hwmod_for_each(_init, NULL);
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/mach-omap2/pdata-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ static void pdata_quirks_check(struct pdata_init *quirks)

void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
{
struct device_node *np;

/*
* We still need this for omap2420 and omap3 PM to work, others are
* using drivers/misc/sram.c already.
Expand All @@ -591,6 +593,15 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
if (of_machine_is_compatible("ti,omap3"))
omap3_mcbsp_init();
pdata_quirks_check(auxdata_quirks);

/* Populate always-on PRCM in l4_wkup to probe l4_wkup */
np = of_find_node_by_name(NULL, "prcm");
if (!np)
np = of_find_node_by_name(NULL, "prm");
if (np)
of_platform_populate(np, omap_dt_match_table,
omap_auxdata_lookup, NULL);

of_platform_populate(NULL, omap_dt_match_table,
omap_auxdata_lookup, NULL);
pdata_quirks_check(pdata_quirks);
Expand Down
68 changes: 48 additions & 20 deletions drivers/bus/ti-sysc.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ static int sysc_wait_softreset(struct sysc *ddata)
u32 sysc_mask, syss_done, rstval;
int syss_offset, error = 0;

if (ddata->cap->regbits->srst_shift < 0)
return 0;

syss_offset = ddata->offsets[SYSC_SYSSTATUS];
sysc_mask = BIT(ddata->cap->regbits->srst_shift);

Expand Down Expand Up @@ -850,8 +853,12 @@ static int sysc_ioremap(struct sysc *ddata)
*/
static int sysc_map_and_check_registers(struct sysc *ddata)
{
struct device_node *np = ddata->dev->of_node;
int error;

if (!of_get_property(np, "reg", NULL))
return 0;

error = sysc_parse_and_check_child_range(ddata);
if (error)
return error;
Expand Down Expand Up @@ -970,9 +977,15 @@ static int sysc_enable_module(struct device *dev)
return error;
}
}
error = sysc_wait_softreset(ddata);
if (error)
dev_warn(ddata->dev, "OCP softreset timed out\n");
/*
* Some modules like i2c and hdq1w have unusable reset status unless
* the module reset quirk is enabled. Skip status check on enable.
*/
if (!(ddata->cfg.quirks & SYSC_MODULE_QUIRK_ENA_RESETDONE)) {
error = sysc_wait_softreset(ddata);
if (error)
dev_warn(ddata->dev, "OCP softreset timed out\n");
}
if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET)
sysc_disable_opt_clocks(ddata);

Expand Down Expand Up @@ -1213,10 +1226,10 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
ddata->enabled = false;

err_allow_idle:
reset_control_assert(ddata->rsts);

sysc_clkdm_allow_idle(ddata);

reset_control_assert(ddata->rsts);

return error;
}

Expand Down Expand Up @@ -1370,20 +1383,22 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff,
SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff,
SYSC_QUIRK_GPMC_DEBUG),
SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff,
SYSC_QUIRK_OPT_CLKS_NEEDED),
SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
SYSC_MODULE_QUIRK_HDQ1W),
SYSC_MODULE_QUIRK_HDQ1W | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
SYSC_MODULE_QUIRK_HDQ1W),
SYSC_MODULE_QUIRK_HDQ1W | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000036, 0x000000ff,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x0000003c, 0x000000ff,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000040, 0x000000ff,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("gpu", 0x50000000, 0x14, -ENODEV, -ENODEV, 0x00010201, 0xffffffff, 0),
SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff,
SYSC_MODULE_QUIRK_SGX),
Expand Down Expand Up @@ -1805,6 +1820,14 @@ static void sysc_init_module_quirks(struct sysc *ddata)
return;
}

#ifdef CONFIG_OMAP_GPMC_DEBUG
if (ddata->cfg.quirks & SYSC_QUIRK_GPMC_DEBUG) {
ddata->cfg.quirks |= SYSC_QUIRK_NO_RESET_ON_INIT;

return;
}
#endif

if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) {
ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c;
ddata->post_reset_quirk = sysc_post_reset_quirk_i2c;
Expand Down Expand Up @@ -1936,6 +1959,7 @@ static int sysc_reset(struct sysc *ddata)
*/
static int sysc_init_module(struct sysc *ddata)
{
bool rstctrl_deasserted = false;
int error = 0;

error = sysc_clockdomain_init(ddata);
Expand All @@ -1960,6 +1984,7 @@ static int sysc_init_module(struct sysc *ddata)
error = reset_control_deassert(ddata->rsts);
if (error)
goto err_main_clocks;
rstctrl_deasserted = true;
}

ddata->revision = sysc_read_revision(ddata);
Expand All @@ -1969,13 +1994,13 @@ static int sysc_init_module(struct sysc *ddata)
if (ddata->legacy_mode) {
error = sysc_legacy_init(ddata);
if (error)
goto err_reset;
goto err_main_clocks;
}

if (!ddata->legacy_mode) {
error = sysc_enable_module(ddata->dev);
if (error)
goto err_reset;
goto err_main_clocks;
}

error = sysc_reset(ddata);
Expand All @@ -1985,10 +2010,6 @@ static int sysc_init_module(struct sysc *ddata)
if (error && !ddata->legacy_mode)
sysc_disable_module(ddata->dev);

err_reset:
if (error && !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);

err_main_clocks:
if (error)
sysc_disable_main_clocks(ddata);
Expand All @@ -1999,6 +2020,10 @@ static int sysc_init_module(struct sysc *ddata)
sysc_clkdm_allow_idle(ddata);
}

if (error && rstctrl_deasserted &&
!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);

return error;
}

Expand Down Expand Up @@ -2900,6 +2925,9 @@ static int sysc_probe(struct platform_device *pdev)
if (!ddata)
return -ENOMEM;

ddata->offsets[SYSC_REVISION] = -ENODEV;
ddata->offsets[SYSC_SYSCONFIG] = -ENODEV;
ddata->offsets[SYSC_SYSSTATUS] = -ENODEV;
ddata->dev = &pdev->dev;
platform_set_drvdata(pdev, ddata);

Expand Down Expand Up @@ -2966,16 +2994,16 @@ static int sysc_probe(struct platform_device *pdev)
}

/* Balance use counts as PM runtime should have enabled these all */
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);

if (!(ddata->cfg.quirks &
(SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
sysc_disable_main_clocks(ddata);
sysc_disable_opt_clocks(ddata);
sysc_clkdm_allow_idle(ddata);
}

if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);

sysc_show_registers(ddata);

ddata->dev->type = &sysc_device_type;
Expand Down
2 changes: 2 additions & 0 deletions drivers/clk/ti/clk-33xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ static const char *enable_init_clks[] = {
"dpll_ddr_m2_ck",
"dpll_mpu_m2_ck",
"l3_gclk",
/* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */
"l3-clkctrl:00bc:0",
"l4hs_gclk",
"l4fw_gclk",
"l4ls_gclk",
Expand Down
41 changes: 28 additions & 13 deletions drivers/remoteproc/wkup_m3_rproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>

#include <linux/platform_data/wkup_m3.h>

Expand All @@ -43,11 +44,13 @@ struct wkup_m3_mem {
* @rproc: rproc handle
* @pdev: pointer to platform device
* @mem: WkupM3 memory information
* @rsts: reset control
*/
struct wkup_m3_rproc {
struct rproc *rproc;
struct platform_device *pdev;
struct wkup_m3_mem mem[WKUPM3_MEM_MAX];
struct reset_control *rsts;
};

static int wkup_m3_rproc_start(struct rproc *rproc)
Expand All @@ -56,13 +59,16 @@ static int wkup_m3_rproc_start(struct rproc *rproc)
struct platform_device *pdev = wkupm3->pdev;
struct device *dev = &pdev->dev;
struct wkup_m3_platform_data *pdata = dev_get_platdata(dev);
int error = 0;

if (pdata->deassert_reset(pdev, pdata->reset_name)) {
error = reset_control_deassert(wkupm3->rsts);

if (!wkupm3->rsts && pdata->deassert_reset(pdev, pdata->reset_name)) {
dev_err(dev, "Unable to reset wkup_m3!\n");
return -ENODEV;
error = -ENODEV;
}

return 0;
return error;
}

static int wkup_m3_rproc_stop(struct rproc *rproc)
Expand All @@ -71,13 +77,16 @@ static int wkup_m3_rproc_stop(struct rproc *rproc)
struct platform_device *pdev = wkupm3->pdev;
struct device *dev = &pdev->dev;
struct wkup_m3_platform_data *pdata = dev_get_platdata(dev);
int error = 0;

if (pdata->assert_reset(pdev, pdata->reset_name)) {
error = reset_control_assert(wkupm3->rsts);

if (!wkupm3->rsts && pdata->assert_reset(pdev, pdata->reset_name)) {
dev_err(dev, "Unable to assert reset of wkup_m3!\n");
return -ENODEV;
error = -ENODEV;
}

return 0;
return error;
}

static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
Expand Down Expand Up @@ -132,12 +141,6 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
int ret;
int i;

if (!(pdata && pdata->deassert_reset && pdata->assert_reset &&
pdata->reset_name)) {
dev_err(dev, "Platform data missing!\n");
return -ENODEV;
}

ret = of_property_read_string(dev->of_node, "ti,pm-firmware",
&fw_name);
if (ret) {
Expand Down Expand Up @@ -165,6 +168,18 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
wkupm3->rproc = rproc;
wkupm3->pdev = pdev;

wkupm3->rsts = devm_reset_control_get_optional_shared(dev, "rstctrl");
if (IS_ERR(wkupm3->rsts))
return PTR_ERR(wkupm3->rsts);
if (!wkupm3->rsts) {
if (!(pdata && pdata->deassert_reset && pdata->assert_reset &&
pdata->reset_name)) {
dev_err(dev, "Platform data missing!\n");
ret = -ENODEV;
goto err_put_rproc;
}
}

for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
mem_names[i]);
Expand All @@ -173,7 +188,7 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "devm_ioremap_resource failed for resource %d\n",
i);
ret = PTR_ERR(wkupm3->mem[i].cpu_addr);
goto err;
goto err_put_rproc;
}
wkupm3->mem[i].bus_addr = res->start;
wkupm3->mem[i].size = resource_size(res);
Expand Down
Loading

0 comments on commit 80c2500

Please sign in to comment.