Lines Matching +full:de +full:- +full:asserting
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Tero Kristo <t-kristo@ti.com>
18 #include <linux/reset-controller.h>
21 #include <linux/platform_data/ti-prm.h>
32 unsigned long statechange:1; /* Optional low-power state change */
126 { .rst = -1 },
132 { .rst = -1 },
139 { .rst = -1 },
181 { .rst = -1 },
186 { .rst = -1 },
203 { .rst = -1 },
209 { .rst = -1 },
225 { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data },
226 { .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data },
227 { .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data },
228 { .compatible = "ti,am3-prm-inst", .data = am3_prm_data },
229 { .compatible = "ti,am4-prm-inst", .data = am4_prm_data },
237 dev_dbg(prmd->dev, "%s %s: %08x/%08x\n", in omap_prm_domain_show_state()
238 prmd->pd.name, desc, in omap_prm_domain_show_state()
239 readl_relaxed(prmd->prm->base + prmd->pwrstctrl), in omap_prm_domain_show_state()
240 readl_relaxed(prmd->prm->base + prmd->pwrstst)); in omap_prm_domain_show_state()
256 if (!prmd->cap) in omap_prm_domain_power_on()
261 if (prmd->pwrstctrl_saved) in omap_prm_domain_power_on()
262 v = prmd->pwrstctrl_saved; in omap_prm_domain_power_on()
264 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_on()
267 prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_on()
270 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, in omap_prm_domain_power_on()
274 dev_err(prmd->dev, "%s: %s timed out\n", in omap_prm_domain_power_on()
275 prmd->pd.name, __func__); in omap_prm_domain_power_on()
285 return __ffs(prmd->cap->usable_modes); in omap_prm_domain_find_lowest()
295 if (!prmd->cap) in omap_prm_domain_power_off()
300 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_off()
301 prmd->pwrstctrl_saved = v; in omap_prm_domain_power_off()
306 if (prmd->cap->statechange) in omap_prm_domain_power_off()
308 if (prmd->cap->logicretstate) in omap_prm_domain_power_off()
313 writel_relaxed(v, prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_off()
316 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, in omap_prm_domain_power_off()
320 dev_warn(prmd->dev, "%s: %s timed out\n", in omap_prm_domain_power_off()
321 __func__, prmd->pd.name); in omap_prm_domain_power_off()
338 np = dev->of_node; in omap_prm_domain_attach_dev()
340 ret = of_parse_phandle_with_args(np, "power-domains", in omap_prm_domain_attach_dev()
341 "#power-domain-cells", 0, &pd_args); in omap_prm_domain_attach_dev()
346 dev_warn(dev, "%s: unusupported #power-domain-cells: %i\n", in omap_prm_domain_attach_dev()
347 prmd->pd.name, pd_args.args_count); in omap_prm_domain_attach_dev()
350 genpd_data->data = NULL; in omap_prm_domain_attach_dev()
361 genpd_data->data = NULL; in omap_prm_domain_detach_dev()
367 struct device_node *np = dev->of_node; in omap_prm_domain_init()
372 if (!of_find_property(dev->of_node, "#power-domain-cells", NULL)) in omap_prm_domain_init()
375 of_node_put(dev->of_node); in omap_prm_domain_init()
379 return -ENOMEM; in omap_prm_domain_init()
381 data = prm->data; in omap_prm_domain_init()
383 data->name); in omap_prm_domain_init()
385 prmd->dev = dev; in omap_prm_domain_init()
386 prmd->prm = prm; in omap_prm_domain_init()
387 prmd->cap = prmd->prm->data->dmap; in omap_prm_domain_init()
388 prmd->pwrstctrl = prmd->prm->data->pwrstctrl; in omap_prm_domain_init()
389 prmd->pwrstst = prmd->prm->data->pwrstst; in omap_prm_domain_init()
391 prmd->pd.name = name; in omap_prm_domain_init()
392 prmd->pd.power_on = omap_prm_domain_power_on; in omap_prm_domain_init()
393 prmd->pd.power_off = omap_prm_domain_power_off; in omap_prm_domain_init()
394 prmd->pd.attach_dev = omap_prm_domain_attach_dev; in omap_prm_domain_init()
395 prmd->pd.detach_dev = omap_prm_domain_detach_dev; in omap_prm_domain_init()
397 pm_genpd_init(&prmd->pd, NULL, true); in omap_prm_domain_init()
398 error = of_genpd_add_provider_simple(np, &prmd->pd); in omap_prm_domain_init()
400 pm_genpd_remove(&prmd->pd); in omap_prm_domain_init()
402 prm->prmd = prmd; in omap_prm_domain_init()
409 if (reset->mask & BIT(id)) in _is_valid_reset()
418 const struct omap_rst_map *map = reset->prm->data->rstmap; in omap_reset_get_st_bit()
420 while (map->rst >= 0) { in omap_reset_get_st_bit()
421 if (map->rst == id) in omap_reset_get_st_bit()
422 return map->st; in omap_reset_get_st_bit()
436 bool has_rstst = reset->prm->data->rstst || in omap_reset_status()
437 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); in omap_reset_status()
441 return -ENOTSUPP; in omap_reset_status()
444 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_reset_status()
452 v = readl_relaxed(reset->prm->base + reset->prm->data->rstst); in omap_reset_status()
467 spin_lock_irqsave(&reset->lock, flags); in omap_reset_assert()
468 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_reset_assert()
470 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); in omap_reset_assert()
471 spin_unlock_irqrestore(&reset->lock, flags); in omap_reset_assert()
484 struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev); in omap_reset_deassert()
491 has_rstst = reset->prm->data->rstst || in omap_reset_deassert()
492 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); in omap_reset_deassert()
499 writel_relaxed(v, reset->prm->base + reset->prm->data->rstst); in omap_reset_deassert()
502 if (reset->clkdm) in omap_reset_deassert()
503 pdata->clkdm_deny_idle(reset->clkdm); in omap_reset_deassert()
505 /* de-assert the reset control line */ in omap_reset_deassert()
506 spin_lock_irqsave(&reset->lock, flags); in omap_reset_deassert()
507 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_reset_deassert()
509 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); in omap_reset_deassert()
510 spin_unlock_irqrestore(&reset->lock, flags); in omap_reset_deassert()
513 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + in omap_reset_deassert()
514 reset->prm->data->rstctrl, in omap_reset_deassert()
519 reset->prm->data->name, id); in omap_reset_deassert()
523 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + in omap_reset_deassert()
524 reset->prm->data->rstst, in omap_reset_deassert()
529 reset->prm->data->name, id); in omap_reset_deassert()
532 if (reset->clkdm) in omap_reset_deassert()
533 pdata->clkdm_allow_idle(reset->clkdm); in omap_reset_deassert()
549 if (!_is_valid_reset(reset, reset_spec->args[0])) in omap_prm_reset_xlate()
550 return -EINVAL; in omap_prm_reset_xlate()
552 return reset_spec->args[0]; in omap_prm_reset_xlate()
560 struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev); in omap_prm_reset_init()
565 * Check if we have controllable resets. If either rstctrl is non-zero in omap_prm_reset_init()
569 if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL)) in omap_prm_reset_init()
573 if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle || in omap_prm_reset_init()
574 !pdata->clkdm_allow_idle) in omap_prm_reset_init()
575 return -EINVAL; in omap_prm_reset_init()
577 map = prm->data->rstmap; in omap_prm_reset_init()
579 return -EINVAL; in omap_prm_reset_init()
581 reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); in omap_prm_reset_init()
583 return -ENOMEM; in omap_prm_reset_init()
585 reset->rcdev.owner = THIS_MODULE; in omap_prm_reset_init()
586 reset->rcdev.ops = &omap_reset_ops; in omap_prm_reset_init()
587 reset->rcdev.of_node = pdev->dev.of_node; in omap_prm_reset_init()
588 reset->rcdev.nr_resets = OMAP_MAX_RESETS; in omap_prm_reset_init()
589 reset->rcdev.of_xlate = omap_prm_reset_xlate; in omap_prm_reset_init()
590 reset->rcdev.of_reset_n_cells = 1; in omap_prm_reset_init()
591 reset->dev = &pdev->dev; in omap_prm_reset_init()
592 spin_lock_init(&reset->lock); in omap_prm_reset_init()
594 reset->prm = prm; in omap_prm_reset_init()
596 sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name : in omap_prm_reset_init()
597 prm->data->name); in omap_prm_reset_init()
599 if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) { in omap_prm_reset_init()
600 reset->clkdm = pdata->clkdm_lookup(buf); in omap_prm_reset_init()
601 if (!reset->clkdm) in omap_prm_reset_init()
602 return -EINVAL; in omap_prm_reset_init()
605 while (map->rst >= 0) { in omap_prm_reset_init()
606 reset->mask |= BIT(map->rst); in omap_prm_reset_init()
611 if (prm->data->rstmap == rst_map_012) { in omap_prm_reset_init()
612 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_prm_reset_init()
613 if ((v & reset->mask) != reset->mask) { in omap_prm_reset_init()
614 dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v); in omap_prm_reset_init()
615 writel_relaxed(reset->mask, reset->prm->base + in omap_prm_reset_init()
616 reset->prm->data->rstctrl); in omap_prm_reset_init()
620 return devm_reset_controller_register(&pdev->dev, &reset->rcdev); in omap_prm_reset_init()
633 return -ENODEV; in omap_prm_probe()
635 match = of_match_device(omap_prm_id_table, &pdev->dev); in omap_prm_probe()
637 return -ENOTSUPP; in omap_prm_probe()
639 prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL); in omap_prm_probe()
641 return -ENOMEM; in omap_prm_probe()
643 data = match->data; in omap_prm_probe()
645 while (data->base != res->start) { in omap_prm_probe()
646 if (!data->base) in omap_prm_probe()
647 return -EINVAL; in omap_prm_probe()
651 prm->data = data; in omap_prm_probe()
653 prm->base = devm_ioremap_resource(&pdev->dev, res); in omap_prm_probe()
654 if (IS_ERR(prm->base)) in omap_prm_probe()
655 return PTR_ERR(prm->base); in omap_prm_probe()
657 ret = omap_prm_domain_init(&pdev->dev, prm); in omap_prm_probe()
668 of_genpd_del_provider(pdev->dev.of_node); in omap_prm_probe()
669 pm_genpd_remove(&prm->prmd->pd); in omap_prm_probe()