Lines Matching +full:device +full:- +full:id +full:- +full:base
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>
11 #include <linux/device.h>
19 #include <linux/reset-controller.h>
24 #include <linux/platform_data/ti-prm.h>
35 unsigned long statechange:1; /* Optional low-power state change */
40 struct device *dev;
56 u32 base; member
70 void __iomem *base; member
80 struct device *dev;
142 { .rst = -1 },
148 { .rst = -1 },
155 { .rst = -1 },
160 .name = "mpu", .base = 0x4a306300,
164 .name = "tesla", .base = 0x4a306400,
169 .name = "abe", .base = 0x4a306500,
173 .name = "always_on_core", .base = 0x4a306600,
177 .name = "core", .base = 0x4a306700,
184 .name = "ivahd", .base = 0x4a306f00,
189 .name = "cam", .base = 0x4a307000,
193 .name = "dss", .base = 0x4a307100,
197 .name = "gfx", .base = 0x4a307200,
201 .name = "l3init", .base = 0x4a307300,
205 .name = "l4per", .base = 0x4a307400,
210 .name = "cefuse", .base = 0x4a307600,
214 .name = "wkup", .base = 0x4a307700,
218 .name = "emu", .base = 0x4a307900,
222 .name = "device", .base = 0x4a307b00,
231 .name = "mpu", .base = 0x4ae06300,
235 .name = "dsp", .base = 0x4ae06400,
240 .name = "abe", .base = 0x4ae06500,
244 .name = "coreaon", .base = 0x4ae06600,
248 .name = "core", .base = 0x4ae06700,
254 .name = "iva", .base = 0x4ae07200,
259 .name = "cam", .base = 0x4ae07300,
263 .name = "dss", .base = 0x4ae07400,
267 .name = "gpu", .base = 0x4ae07500,
271 .name = "l3init", .base = 0x4ae07600,
275 .name = "custefuse", .base = 0x4ae07700,
279 .name = "wkupaon", .base = 0x4ae07800,
283 .name = "emu", .base = 0x4ae07a00,
287 .name = "device", .base = 0x4ae07c00,
296 .name = "mpu", .base = 0x4ae06300,
300 .name = "dsp1", .base = 0x4ae06400,
305 .name = "ipu", .base = 0x4ae06500,
311 .name = "coreaon", .base = 0x4ae06628,
315 .name = "core", .base = 0x4ae06700,
321 .name = "iva", .base = 0x4ae06f00,
326 .name = "cam", .base = 0x4ae07000,
330 .name = "dss", .base = 0x4ae07100,
334 .name = "gpu", .base = 0x4ae07200,
338 .name = "l3init", .base = 0x4ae07300,
344 .name = "l4per", .base = 0x4ae07400,
348 .name = "custefuse", .base = 0x4ae07600,
352 .name = "wkupaon", .base = 0x4ae07724,
356 .name = "emu", .base = 0x4ae07900,
360 .name = "dsp2", .base = 0x4ae07b00,
365 .name = "eve1", .base = 0x4ae07b40,
370 .name = "eve2", .base = 0x4ae07b80,
375 .name = "eve3", .base = 0x4ae07bc0,
380 .name = "eve4", .base = 0x4ae07c00,
385 .name = "rtc", .base = 0x4ae07c60,
389 .name = "vpe", .base = 0x4ae07c80,
397 { .rst = -1 },
402 { .rst = -1 },
407 .name = "per", .base = 0x44e00c00,
414 .name = "wkup", .base = 0x44e00d00,
420 .name = "mpu", .base = 0x44e00e00,
424 .name = "device", .base = 0x44e00f00,
429 .name = "rtc", .base = 0x44e01000,
433 .name = "gfx", .base = 0x44e01100,
438 .name = "cefuse", .base = 0x44e01200,
446 { .rst = -1 },
452 { .rst = -1 },
457 .name = "mpu", .base = 0x44df0300,
461 .name = "gfx", .base = 0x44df0400,
466 .name = "rtc", .base = 0x44df0500,
470 .name = "tamper", .base = 0x44df0600,
474 .name = "cefuse", .base = 0x44df0700,
478 .name = "per", .base = 0x44df0800,
484 .name = "wkup", .base = 0x44df2000,
490 .name = "device", .base = 0x44df4000,
498 { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data },
499 { .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data },
500 { .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data },
501 { .compatible = "ti,am3-prm-inst", .data = am3_prm_data },
502 { .compatible = "ti,am4-prm-inst", .data = am4_prm_data },
510 dev_dbg(prmd->dev, "%s %s: %08x/%08x\n", in omap_prm_domain_show_state()
511 prmd->pd.name, desc, in omap_prm_domain_show_state()
512 readl_relaxed(prmd->prm->base + prmd->pwrstctrl), in omap_prm_domain_show_state()
513 readl_relaxed(prmd->prm->base + prmd->pwrstst)); in omap_prm_domain_show_state()
529 if (!prmd->cap) in omap_prm_domain_power_on()
534 if (prmd->pwrstctrl_saved) in omap_prm_domain_power_on()
535 v = prmd->pwrstctrl_saved; in omap_prm_domain_power_on()
537 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_on()
539 if (prmd->prm->data->flags & OMAP_PRM_RET_WHEN_IDLE) in omap_prm_domain_power_on()
545 prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_on()
548 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, in omap_prm_domain_power_on()
552 dev_err(prmd->dev, "%s: %s timed out\n", in omap_prm_domain_power_on()
553 prmd->pd.name, __func__); in omap_prm_domain_power_on()
563 return __ffs(prmd->cap->usable_modes); in omap_prm_domain_find_lowest()
573 if (!prmd->cap) in omap_prm_domain_power_off()
578 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_off()
579 prmd->pwrstctrl_saved = v; in omap_prm_domain_power_off()
584 if (prmd->cap->statechange) in omap_prm_domain_power_off()
586 if (prmd->cap->logicretstate) in omap_prm_domain_power_off()
591 writel_relaxed(v, prmd->prm->base + prmd->pwrstctrl); in omap_prm_domain_power_off()
594 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, in omap_prm_domain_power_off()
598 dev_warn(prmd->dev, "%s: %s timed out\n", in omap_prm_domain_power_off()
599 __func__, prmd->pd.name); in omap_prm_domain_power_off()
607 * Note that ti-sysc already manages the module clocks separately so
609 * for simple-pm-bus.
611 static int omap_prm_domain_attach_clock(struct device *dev, in omap_prm_domain_attach_clock()
614 struct device_node *np = dev->of_node; in omap_prm_domain_attach_clock()
617 if (!of_device_is_compatible(np, "simple-pm-bus")) in omap_prm_domain_attach_clock()
633 prmd->uses_pm_clk = 1; in omap_prm_domain_attach_clock()
639 struct device *dev) in omap_prm_domain_attach_dev()
648 np = dev->of_node; in omap_prm_domain_attach_dev()
650 ret = of_parse_phandle_with_args(np, "power-domains", in omap_prm_domain_attach_dev()
651 "#power-domain-cells", 0, &pd_args); in omap_prm_domain_attach_dev()
656 dev_warn(dev, "%s: unusupported #power-domain-cells: %i\n", in omap_prm_domain_attach_dev()
657 prmd->pd.name, pd_args.args_count); in omap_prm_domain_attach_dev()
660 genpd_data->data = NULL; in omap_prm_domain_attach_dev()
670 struct device *dev) in omap_prm_domain_detach_dev()
676 if (prmd->uses_pm_clk) in omap_prm_domain_detach_dev()
679 genpd_data->data = NULL; in omap_prm_domain_detach_dev()
682 static int omap_prm_domain_init(struct device *dev, struct omap_prm *prm) in omap_prm_domain_init()
685 struct device_node *np = dev->of_node; in omap_prm_domain_init()
690 if (!of_property_present(dev->of_node, "#power-domain-cells")) in omap_prm_domain_init()
693 of_node_put(dev->of_node); in omap_prm_domain_init()
697 return -ENOMEM; in omap_prm_domain_init()
699 data = prm->data; in omap_prm_domain_init()
701 data->name); in omap_prm_domain_init()
703 return -ENOMEM; in omap_prm_domain_init()
705 prmd->dev = dev; in omap_prm_domain_init()
706 prmd->prm = prm; in omap_prm_domain_init()
707 prmd->cap = prmd->prm->data->dmap; in omap_prm_domain_init()
708 prmd->pwrstctrl = prmd->prm->data->pwrstctrl; in omap_prm_domain_init()
709 prmd->pwrstst = prmd->prm->data->pwrstst; in omap_prm_domain_init()
711 prmd->pd.name = name; in omap_prm_domain_init()
712 prmd->pd.power_on = omap_prm_domain_power_on; in omap_prm_domain_init()
713 prmd->pd.power_off = omap_prm_domain_power_off; in omap_prm_domain_init()
714 prmd->pd.attach_dev = omap_prm_domain_attach_dev; in omap_prm_domain_init()
715 prmd->pd.detach_dev = omap_prm_domain_detach_dev; in omap_prm_domain_init()
716 prmd->pd.flags = GENPD_FLAG_PM_CLK; in omap_prm_domain_init()
718 pm_genpd_init(&prmd->pd, NULL, true); in omap_prm_domain_init()
719 error = of_genpd_add_provider_simple(np, &prmd->pd); in omap_prm_domain_init()
721 pm_genpd_remove(&prmd->pd); in omap_prm_domain_init()
723 prm->prmd = prmd; in omap_prm_domain_init()
728 static bool _is_valid_reset(struct omap_reset_data *reset, unsigned long id) in _is_valid_reset() argument
730 if (reset->mask & BIT(id)) in _is_valid_reset()
737 unsigned long id) in omap_reset_get_st_bit() argument
739 const struct omap_rst_map *map = reset->prm->data->rstmap; in omap_reset_get_st_bit()
741 while (map->rst >= 0) { in omap_reset_get_st_bit()
742 if (map->rst == id) in omap_reset_get_st_bit()
743 return map->st; in omap_reset_get_st_bit()
748 return id; in omap_reset_get_st_bit()
752 unsigned long id) in omap_reset_status() argument
756 int st_bit = omap_reset_get_st_bit(reset, id); in omap_reset_status()
757 bool has_rstst = reset->prm->data->rstst || in omap_reset_status()
758 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); in omap_reset_status()
762 return -ENOTSUPP; in omap_reset_status()
765 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_reset_status()
766 if (v & BIT(id)) in omap_reset_status()
773 v = readl_relaxed(reset->prm->base + reset->prm->data->rstst); in omap_reset_status()
781 unsigned long id) in omap_reset_assert() argument
788 spin_lock_irqsave(&reset->lock, flags); in omap_reset_assert()
789 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_reset_assert()
790 v |= 1 << id; in omap_reset_assert()
791 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); in omap_reset_assert()
792 spin_unlock_irqrestore(&reset->lock, flags); in omap_reset_assert()
798 unsigned long id) in omap_reset_deassert() argument
805 struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev); in omap_reset_deassert()
809 if (!omap_reset_status(rcdev, id)) in omap_reset_deassert()
812 has_rstst = reset->prm->data->rstst || in omap_reset_deassert()
813 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); in omap_reset_deassert()
816 st_bit = omap_reset_get_st_bit(reset, id); in omap_reset_deassert()
820 writel_relaxed(v, reset->prm->base + reset->prm->data->rstst); in omap_reset_deassert()
823 if (reset->clkdm) in omap_reset_deassert()
824 pdata->clkdm_deny_idle(reset->clkdm); in omap_reset_deassert()
826 /* de-assert the reset control line */ in omap_reset_deassert()
827 spin_lock_irqsave(&reset->lock, flags); in omap_reset_deassert()
828 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_reset_deassert()
829 v &= ~(1 << id); in omap_reset_deassert()
830 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); in omap_reset_deassert()
831 spin_unlock_irqrestore(&reset->lock, flags); in omap_reset_deassert()
834 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + in omap_reset_deassert()
835 reset->prm->data->rstctrl, in omap_reset_deassert()
836 v, !(v & BIT(id)), 1, in omap_reset_deassert()
840 reset->prm->data->name, id); in omap_reset_deassert()
844 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + in omap_reset_deassert()
845 reset->prm->data->rstst, in omap_reset_deassert()
850 reset->prm->data->name, id); in omap_reset_deassert()
853 if (reset->clkdm) in omap_reset_deassert()
854 pdata->clkdm_allow_idle(reset->clkdm); in omap_reset_deassert()
870 if (!_is_valid_reset(reset, reset_spec->args[0])) in omap_prm_reset_xlate()
871 return -EINVAL; in omap_prm_reset_xlate()
873 return reset_spec->args[0]; in omap_prm_reset_xlate()
881 struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev); in omap_prm_reset_init()
886 * Check if we have controllable resets. If either rstctrl is non-zero in omap_prm_reset_init()
890 if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL)) in omap_prm_reset_init()
894 if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle || in omap_prm_reset_init()
895 !pdata->clkdm_allow_idle) in omap_prm_reset_init()
896 return -EINVAL; in omap_prm_reset_init()
898 map = prm->data->rstmap; in omap_prm_reset_init()
900 return -EINVAL; in omap_prm_reset_init()
902 reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); in omap_prm_reset_init()
904 return -ENOMEM; in omap_prm_reset_init()
906 reset->rcdev.owner = THIS_MODULE; in omap_prm_reset_init()
907 reset->rcdev.ops = &omap_reset_ops; in omap_prm_reset_init()
908 reset->rcdev.of_node = pdev->dev.of_node; in omap_prm_reset_init()
909 reset->rcdev.nr_resets = OMAP_MAX_RESETS; in omap_prm_reset_init()
910 reset->rcdev.of_xlate = omap_prm_reset_xlate; in omap_prm_reset_init()
911 reset->rcdev.of_reset_n_cells = 1; in omap_prm_reset_init()
912 reset->dev = &pdev->dev; in omap_prm_reset_init()
913 spin_lock_init(&reset->lock); in omap_prm_reset_init()
915 reset->prm = prm; in omap_prm_reset_init()
917 sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name : in omap_prm_reset_init()
918 prm->data->name); in omap_prm_reset_init()
920 if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) { in omap_prm_reset_init()
921 reset->clkdm = pdata->clkdm_lookup(buf); in omap_prm_reset_init()
922 if (!reset->clkdm) in omap_prm_reset_init()
923 return -EINVAL; in omap_prm_reset_init()
926 while (map->rst >= 0) { in omap_prm_reset_init()
927 reset->mask |= BIT(map->rst); in omap_prm_reset_init()
932 if (prm->data->rstmap == rst_map_012) { in omap_prm_reset_init()
933 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); in omap_prm_reset_init()
934 if ((v & reset->mask) != reset->mask) { in omap_prm_reset_init()
935 dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v); in omap_prm_reset_init()
936 writel_relaxed(reset->mask, reset->prm->base + in omap_prm_reset_init()
937 reset->prm->data->rstctrl); in omap_prm_reset_init()
941 return devm_reset_controller_register(&pdev->dev, &reset->rcdev); in omap_prm_reset_init()
951 data = of_device_get_match_data(&pdev->dev); in omap_prm_probe()
953 return -ENOTSUPP; in omap_prm_probe()
955 prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL); in omap_prm_probe()
957 return -ENOMEM; in omap_prm_probe()
959 prm->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in omap_prm_probe()
960 if (IS_ERR(prm->base)) in omap_prm_probe()
961 return PTR_ERR(prm->base); in omap_prm_probe()
963 while (data->base != res->start) { in omap_prm_probe()
964 if (!data->base) in omap_prm_probe()
965 return -EINVAL; in omap_prm_probe()
969 prm->data = data; in omap_prm_probe()
971 ret = omap_prm_domain_init(&pdev->dev, prm); in omap_prm_probe()
982 of_genpd_del_provider(pdev->dev.of_node); in omap_prm_probe()
983 pm_genpd_remove(&prm->prmd->pd); in omap_prm_probe()