Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only OR MIT
0002 /*
0003  * Apple SoC PMGR device power state driver
0004  *
0005  * Copyright The Asahi Linux Contributors
0006  */
0007 
0008 #include <linux/bitops.h>
0009 #include <linux/bitfield.h>
0010 #include <linux/err.h>
0011 #include <linux/of.h>
0012 #include <linux/of_address.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/pm_domain.h>
0015 #include <linux/regmap.h>
0016 #include <linux/mfd/syscon.h>
0017 #include <linux/reset-controller.h>
0018 #include <linux/module.h>
0019 
0020 #define APPLE_PMGR_RESET        BIT(31)
0021 #define APPLE_PMGR_AUTO_ENABLE  BIT(28)
0022 #define APPLE_PMGR_PS_AUTO      GENMASK(27, 24)
0023 #define APPLE_PMGR_PS_MIN       GENMASK(19, 16)
0024 #define APPLE_PMGR_PARENT_OFF   BIT(11)
0025 #define APPLE_PMGR_DEV_DISABLE  BIT(10)
0026 #define APPLE_PMGR_WAS_CLKGATED BIT(9)
0027 #define APPLE_PMGR_WAS_PWRGATED BIT(8)
0028 #define APPLE_PMGR_PS_ACTUAL    GENMASK(7, 4)
0029 #define APPLE_PMGR_PS_TARGET    GENMASK(3, 0)
0030 
0031 #define APPLE_PMGR_FLAGS        (APPLE_PMGR_WAS_CLKGATED | APPLE_PMGR_WAS_PWRGATED)
0032 
0033 #define APPLE_PMGR_PS_ACTIVE    0xf
0034 #define APPLE_PMGR_PS_CLKGATE   0x4
0035 #define APPLE_PMGR_PS_PWRGATE   0x0
0036 
0037 #define APPLE_PMGR_PS_SET_TIMEOUT 100
0038 #define APPLE_PMGR_RESET_TIME 1
0039 
0040 struct apple_pmgr_ps {
0041     struct device *dev;
0042     struct generic_pm_domain genpd;
0043     struct reset_controller_dev rcdev;
0044     struct regmap *regmap;
0045     u32 offset;
0046     u32 min_state;
0047 };
0048 
0049 #define genpd_to_apple_pmgr_ps(_genpd) container_of(_genpd, struct apple_pmgr_ps, genpd)
0050 #define rcdev_to_apple_pmgr_ps(_rcdev) container_of(_rcdev, struct apple_pmgr_ps, rcdev)
0051 
0052 static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool auto_enable)
0053 {
0054     int ret;
0055     struct apple_pmgr_ps *ps = genpd_to_apple_pmgr_ps(genpd);
0056     u32 reg;
0057 
0058     ret = regmap_read(ps->regmap, ps->offset, &reg);
0059     if (ret < 0)
0060         return ret;
0061 
0062     /* Resets are synchronous, and only work if the device is powered and clocked. */
0063     if (reg & APPLE_PMGR_RESET && pstate != APPLE_PMGR_PS_ACTIVE)
0064         dev_err(ps->dev, "PS %s: powering off with RESET active\n",
0065             genpd->name);
0066 
0067     reg &= ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET);
0068     reg |= FIELD_PREP(APPLE_PMGR_PS_TARGET, pstate);
0069 
0070     dev_dbg(ps->dev, "PS %s: pwrstate = 0x%x: 0x%x\n", genpd->name, pstate, reg);
0071 
0072     regmap_write(ps->regmap, ps->offset, reg);
0073 
0074     ret = regmap_read_poll_timeout_atomic(
0075         ps->regmap, ps->offset, reg,
0076         (FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == pstate), 1,
0077         APPLE_PMGR_PS_SET_TIMEOUT);
0078     if (ret < 0)
0079         dev_err(ps->dev, "PS %s: Failed to reach power state 0x%x (now: 0x%x)\n",
0080             genpd->name, pstate, reg);
0081 
0082     if (auto_enable) {
0083         /* Not all devices implement this; this is a no-op where not implemented. */
0084         reg &= ~APPLE_PMGR_FLAGS;
0085         reg |= APPLE_PMGR_AUTO_ENABLE;
0086         regmap_write(ps->regmap, ps->offset, reg);
0087     }
0088 
0089     return ret;
0090 }
0091 
0092 static bool apple_pmgr_ps_is_active(struct apple_pmgr_ps *ps)
0093 {
0094     u32 reg = 0;
0095 
0096     regmap_read(ps->regmap, ps->offset, &reg);
0097     /*
0098      * We consider domains as active if they are actually on, or if they have auto-PM
0099      * enabled and the intended target is on.
0100      */
0101     return (FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == APPLE_PMGR_PS_ACTIVE ||
0102         (FIELD_GET(APPLE_PMGR_PS_TARGET, reg) == APPLE_PMGR_PS_ACTIVE &&
0103          reg & APPLE_PMGR_AUTO_ENABLE));
0104 }
0105 
0106 static int apple_pmgr_ps_power_on(struct generic_pm_domain *genpd)
0107 {
0108     return apple_pmgr_ps_set(genpd, APPLE_PMGR_PS_ACTIVE, true);
0109 }
0110 
0111 static int apple_pmgr_ps_power_off(struct generic_pm_domain *genpd)
0112 {
0113     return apple_pmgr_ps_set(genpd, APPLE_PMGR_PS_PWRGATE, false);
0114 }
0115 
0116 static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
0117 {
0118     struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
0119 
0120     mutex_lock(&ps->genpd.mlock);
0121 
0122     if (ps->genpd.status == GENPD_STATE_OFF)
0123         dev_err(ps->dev, "PS 0x%x: asserting RESET while powered down\n", ps->offset);
0124 
0125     dev_dbg(ps->dev, "PS 0x%x: assert reset\n", ps->offset);
0126     /* Quiesce device before asserting reset */
0127     regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_DEV_DISABLE,
0128                APPLE_PMGR_DEV_DISABLE);
0129     regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET,
0130                APPLE_PMGR_RESET);
0131 
0132     mutex_unlock(&ps->genpd.mlock);
0133 
0134     return 0;
0135 }
0136 
0137 static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
0138 {
0139     struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
0140 
0141     mutex_lock(&ps->genpd.mlock);
0142 
0143     dev_dbg(ps->dev, "PS 0x%x: deassert reset\n", ps->offset);
0144     regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 0);
0145     regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_DEV_DISABLE, 0);
0146 
0147     if (ps->genpd.status == GENPD_STATE_OFF)
0148         dev_err(ps->dev, "PS 0x%x: RESET was deasserted while powered down\n", ps->offset);
0149 
0150     mutex_unlock(&ps->genpd.mlock);
0151 
0152     return 0;
0153 }
0154 
0155 static int apple_pmgr_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
0156 {
0157     int ret;
0158 
0159     ret = apple_pmgr_reset_assert(rcdev, id);
0160     if (ret)
0161         return ret;
0162 
0163     usleep_range(APPLE_PMGR_RESET_TIME, 2 * APPLE_PMGR_RESET_TIME);
0164 
0165     return apple_pmgr_reset_deassert(rcdev, id);
0166 }
0167 
0168 static int apple_pmgr_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
0169 {
0170     struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
0171     u32 reg = 0;
0172 
0173     regmap_read(ps->regmap, ps->offset, &reg);
0174 
0175     return !!(reg & APPLE_PMGR_RESET);
0176 }
0177 
0178 const struct reset_control_ops apple_pmgr_reset_ops = {
0179     .assert     = apple_pmgr_reset_assert,
0180     .deassert   = apple_pmgr_reset_deassert,
0181     .reset      = apple_pmgr_reset_reset,
0182     .status     = apple_pmgr_reset_status,
0183 };
0184 
0185 static int apple_pmgr_reset_xlate(struct reset_controller_dev *rcdev,
0186                   const struct of_phandle_args *reset_spec)
0187 {
0188     return 0;
0189 }
0190 
0191 static int apple_pmgr_ps_probe(struct platform_device *pdev)
0192 {
0193     struct device *dev = &pdev->dev;
0194     struct device_node *node = dev->of_node;
0195     struct apple_pmgr_ps *ps;
0196     struct regmap *regmap;
0197     struct of_phandle_iterator it;
0198     int ret;
0199     const char *name;
0200     bool active;
0201 
0202     regmap = syscon_node_to_regmap(node->parent);
0203     if (IS_ERR(regmap))
0204         return PTR_ERR(regmap);
0205 
0206     ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
0207     if (!ps)
0208         return -ENOMEM;
0209 
0210     ps->dev = dev;
0211     ps->regmap = regmap;
0212 
0213     ret = of_property_read_string(node, "label", &name);
0214     if (ret < 0) {
0215         dev_err(dev, "missing label property\n");
0216         return ret;
0217     }
0218 
0219     ret = of_property_read_u32(node, "reg", &ps->offset);
0220     if (ret < 0) {
0221         dev_err(dev, "missing reg property\n");
0222         return ret;
0223     }
0224 
0225     ps->genpd.name = name;
0226     ps->genpd.power_on = apple_pmgr_ps_power_on;
0227     ps->genpd.power_off = apple_pmgr_ps_power_off;
0228 
0229     ret = of_property_read_u32(node, "apple,min-state", &ps->min_state);
0230     if (ret == 0 && ps->min_state <= APPLE_PMGR_PS_ACTIVE)
0231         regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_PS_MIN,
0232                    FIELD_PREP(APPLE_PMGR_PS_MIN, ps->min_state));
0233 
0234     active = apple_pmgr_ps_is_active(ps);
0235     if (of_property_read_bool(node, "apple,always-on")) {
0236         ps->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
0237         if (!active) {
0238             dev_warn(dev, "always-on domain %s is not on at boot\n", name);
0239             /* Turn it on so pm_genpd_init does not fail */
0240             active = apple_pmgr_ps_power_on(&ps->genpd) == 0;
0241         }
0242     }
0243 
0244     /* Turn on auto-PM if the domain is already on */
0245     if (active)
0246         regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_AUTO_ENABLE,
0247                    APPLE_PMGR_AUTO_ENABLE);
0248 
0249     ret = pm_genpd_init(&ps->genpd, NULL, !active);
0250     if (ret < 0) {
0251         dev_err(dev, "pm_genpd_init failed\n");
0252         return ret;
0253     }
0254 
0255     ret = of_genpd_add_provider_simple(node, &ps->genpd);
0256     if (ret < 0) {
0257         dev_err(dev, "of_genpd_add_provider_simple failed\n");
0258         return ret;
0259     }
0260 
0261     of_for_each_phandle(&it, ret, node, "power-domains", "#power-domain-cells", -1) {
0262         struct of_phandle_args parent, child;
0263 
0264         parent.np = it.node;
0265         parent.args_count = of_phandle_iterator_args(&it, parent.args, MAX_PHANDLE_ARGS);
0266         child.np = node;
0267         child.args_count = 0;
0268         ret = of_genpd_add_subdomain(&parent, &child);
0269 
0270         if (ret == -EPROBE_DEFER) {
0271             of_node_put(parent.np);
0272             goto err_remove;
0273         } else if (ret < 0) {
0274             dev_err(dev, "failed to add to parent domain: %d (%s -> %s)\n",
0275                 ret, it.node->name, node->name);
0276             of_node_put(parent.np);
0277             goto err_remove;
0278         }
0279     }
0280 
0281     /*
0282      * Do not participate in regular PM; parent power domains are handled via the
0283      * genpd hierarchy.
0284      */
0285     pm_genpd_remove_device(dev);
0286 
0287     ps->rcdev.owner = THIS_MODULE;
0288     ps->rcdev.nr_resets = 1;
0289     ps->rcdev.ops = &apple_pmgr_reset_ops;
0290     ps->rcdev.of_node = dev->of_node;
0291     ps->rcdev.of_reset_n_cells = 0;
0292     ps->rcdev.of_xlate = apple_pmgr_reset_xlate;
0293 
0294     ret = devm_reset_controller_register(dev, &ps->rcdev);
0295     if (ret < 0)
0296         goto err_remove;
0297 
0298     return 0;
0299 err_remove:
0300     of_genpd_del_provider(node);
0301     pm_genpd_remove(&ps->genpd);
0302     return ret;
0303 }
0304 
0305 static const struct of_device_id apple_pmgr_ps_of_match[] = {
0306     { .compatible = "apple,pmgr-pwrstate" },
0307     {}
0308 };
0309 
0310 MODULE_DEVICE_TABLE(of, apple_pmgr_ps_of_match);
0311 
0312 static struct platform_driver apple_pmgr_ps_driver = {
0313     .probe = apple_pmgr_ps_probe,
0314     .driver = {
0315         .name = "apple-pmgr-pwrstate",
0316         .of_match_table = apple_pmgr_ps_of_match,
0317     },
0318 };
0319 
0320 MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
0321 MODULE_DESCRIPTION("PMGR power state driver for Apple SoCs");
0322 MODULE_LICENSE("GPL v2");
0323 
0324 module_platform_driver(apple_pmgr_ps_driver);