Loading Documentation/devicetree/bindings/regulator/gdsc-regulator.txt +3 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,9 @@ Optional properties: - reset-names: reset signal name strings sorted in the same order as the resets property. These can be supplied only if we support qcom,skip-logic-collapse. - qcom,poll-cfg-gdscr: Poll the CFG register of the GDSC to determine if the GDSC is enabled/disabled. This flag should not be set in conjunction with "hw-ctrl-addr". Example: gdsc_oxili_gx: qcom,gdsc@fd8c4024 { Loading drivers/clk/qcom/gdsc-regulator.c +66 −10 Original line number Diff line number Diff line Loading @@ -36,6 +36,10 @@ #define HW_CONTROL_MASK BIT(1) #define SW_COLLAPSE_MASK BIT(0) /* CFG_GDSCR */ #define GDSC_POWER_UP_COMPLETE BIT(16) #define GDSC_POWER_DOWN_COMPLETE BIT(15) /* Domain Address */ #define GMEM_CLAMP_IO_MASK BIT(0) #define GMEM_RESET_MASK BIT(4) Loading @@ -45,6 +49,7 @@ /* Register Offset */ #define REG_OFFSET 0x0 #define CFG_GDSCR_OFFSET 0x4 /* Timeout Delay */ #define TIMEOUT_US 100 Loading @@ -69,6 +74,7 @@ struct gdsc { bool is_gdsc_enabled; bool allow_clear; bool reset_aon; bool poll_cfg_gdscr; int clock_count; int reset_count; int root_clk_idx; Loading Loading @@ -128,6 +134,31 @@ static int poll_gdsc_status(struct gdsc *sc, enum gdscr_status status) return -ETIMEDOUT; } static int poll_cfg_gdsc_status(struct gdsc *sc, enum gdscr_status status) { struct regmap *regmap = sc->regmap; int count = sc->gds_timeout; u32 val; for (; count > 0; count--) { regmap_read(regmap, CFG_GDSCR_OFFSET, &val); switch (status) { case ENABLED: if (val & GDSC_POWER_UP_COMPLETE) return 0; break; case DISABLED: if (val & GDSC_POWER_DOWN_COMPLETE) return 0; break; } udelay(1); } return -ETIMEDOUT; } static int gdsc_is_enabled(struct regulator_dev *rdev) { struct gdsc *sc = rdev_get_drvdata(rdev); Loading @@ -154,7 +185,7 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) static int gdsc_enable(struct regulator_dev *rdev) { struct gdsc *sc = rdev_get_drvdata(rdev); uint32_t regval, hw_ctrl_regval = 0x0; uint32_t regval, cfg_regval, hw_ctrl_regval = 0x0; int i, ret = 0; mutex_lock(&gdsc_seq_lock); Loading Loading @@ -230,6 +261,9 @@ static int gdsc_enable(struct regulator_dev *rdev) mb(); udelay(1); if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, ENABLED); else ret = poll_gdsc_status(sc, ENABLED); if (ret) { regmap_read(sc->regmap, REG_OFFSET, ®val); Loading Loading @@ -260,11 +294,21 @@ static int gdsc_enable(struct regulator_dev *rdev) regval); udelay(sc->gds_timeout); regmap_read(sc->regmap, REG_OFFSET, ®val); if (sc->poll_cfg_gdscr) { regmap_read(sc->regmap, REG_OFFSET, ®val); regmap_read(sc->regmap, CFG_GDSCR_OFFSET, &cfg_regval); dev_err(&rdev->dev, "%s final state: gdscr - 0x%x, cfg_gdscr - 0x%x (%d us after timeout)\n", sc->rdesc.name, regval, cfg_regval, sc->gds_timeout); } else { regmap_read(sc->regmap, REG_OFFSET, ®val); dev_err(&rdev->dev, "%s final state: 0x%x (%d us after timeout)\n", sc->rdesc.name, regval, sc->gds_timeout); } mutex_unlock(&gdsc_seq_lock); return ret; Loading Loading @@ -346,6 +390,9 @@ static int gdsc_disable(struct regulator_dev *rdev) */ udelay(TIMEOUT_US); } else { if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, DISABLED); else ret = poll_gdsc_status(sc, DISABLED); if (ret) dev_err(&rdev->dev, "%s disable timed out: 0x%x\n", Loading Loading @@ -434,6 +481,9 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode) mb(); udelay(1); if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, ENABLED); else ret = poll_gdsc_status(sc, ENABLED); if (ret) dev_err(&rdev->dev, "%s set_mode timed out: 0x%x\n", Loading Loading @@ -531,6 +581,9 @@ static int gdsc_probe(struct platform_device *pdev) return -ENODEV; } sc->poll_cfg_gdscr = of_property_read_bool(pdev->dev.of_node, "qcom,poll-cfg-gdscr"); sc->gds_timeout = TIMEOUT_US; ret = of_property_read_u32(pdev->dev.of_node, "qcom,gds-timeout", Loading Loading @@ -667,6 +720,9 @@ static int gdsc_probe(struct platform_device *pdev) regval &= ~SW_COLLAPSE_MASK; regmap_write(sc->regmap, REG_OFFSET, regval); if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, ENABLED); else ret = poll_gdsc_status(sc, ENABLED); if (ret) { dev_err(&pdev->dev, "%s enable timed out: 0x%x\n", Loading Loading
Documentation/devicetree/bindings/regulator/gdsc-regulator.txt +3 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,9 @@ Optional properties: - reset-names: reset signal name strings sorted in the same order as the resets property. These can be supplied only if we support qcom,skip-logic-collapse. - qcom,poll-cfg-gdscr: Poll the CFG register of the GDSC to determine if the GDSC is enabled/disabled. This flag should not be set in conjunction with "hw-ctrl-addr". Example: gdsc_oxili_gx: qcom,gdsc@fd8c4024 { Loading
drivers/clk/qcom/gdsc-regulator.c +66 −10 Original line number Diff line number Diff line Loading @@ -36,6 +36,10 @@ #define HW_CONTROL_MASK BIT(1) #define SW_COLLAPSE_MASK BIT(0) /* CFG_GDSCR */ #define GDSC_POWER_UP_COMPLETE BIT(16) #define GDSC_POWER_DOWN_COMPLETE BIT(15) /* Domain Address */ #define GMEM_CLAMP_IO_MASK BIT(0) #define GMEM_RESET_MASK BIT(4) Loading @@ -45,6 +49,7 @@ /* Register Offset */ #define REG_OFFSET 0x0 #define CFG_GDSCR_OFFSET 0x4 /* Timeout Delay */ #define TIMEOUT_US 100 Loading @@ -69,6 +74,7 @@ struct gdsc { bool is_gdsc_enabled; bool allow_clear; bool reset_aon; bool poll_cfg_gdscr; int clock_count; int reset_count; int root_clk_idx; Loading Loading @@ -128,6 +134,31 @@ static int poll_gdsc_status(struct gdsc *sc, enum gdscr_status status) return -ETIMEDOUT; } static int poll_cfg_gdsc_status(struct gdsc *sc, enum gdscr_status status) { struct regmap *regmap = sc->regmap; int count = sc->gds_timeout; u32 val; for (; count > 0; count--) { regmap_read(regmap, CFG_GDSCR_OFFSET, &val); switch (status) { case ENABLED: if (val & GDSC_POWER_UP_COMPLETE) return 0; break; case DISABLED: if (val & GDSC_POWER_DOWN_COMPLETE) return 0; break; } udelay(1); } return -ETIMEDOUT; } static int gdsc_is_enabled(struct regulator_dev *rdev) { struct gdsc *sc = rdev_get_drvdata(rdev); Loading @@ -154,7 +185,7 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) static int gdsc_enable(struct regulator_dev *rdev) { struct gdsc *sc = rdev_get_drvdata(rdev); uint32_t regval, hw_ctrl_regval = 0x0; uint32_t regval, cfg_regval, hw_ctrl_regval = 0x0; int i, ret = 0; mutex_lock(&gdsc_seq_lock); Loading Loading @@ -230,6 +261,9 @@ static int gdsc_enable(struct regulator_dev *rdev) mb(); udelay(1); if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, ENABLED); else ret = poll_gdsc_status(sc, ENABLED); if (ret) { regmap_read(sc->regmap, REG_OFFSET, ®val); Loading Loading @@ -260,11 +294,21 @@ static int gdsc_enable(struct regulator_dev *rdev) regval); udelay(sc->gds_timeout); regmap_read(sc->regmap, REG_OFFSET, ®val); if (sc->poll_cfg_gdscr) { regmap_read(sc->regmap, REG_OFFSET, ®val); regmap_read(sc->regmap, CFG_GDSCR_OFFSET, &cfg_regval); dev_err(&rdev->dev, "%s final state: gdscr - 0x%x, cfg_gdscr - 0x%x (%d us after timeout)\n", sc->rdesc.name, regval, cfg_regval, sc->gds_timeout); } else { regmap_read(sc->regmap, REG_OFFSET, ®val); dev_err(&rdev->dev, "%s final state: 0x%x (%d us after timeout)\n", sc->rdesc.name, regval, sc->gds_timeout); } mutex_unlock(&gdsc_seq_lock); return ret; Loading Loading @@ -346,6 +390,9 @@ static int gdsc_disable(struct regulator_dev *rdev) */ udelay(TIMEOUT_US); } else { if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, DISABLED); else ret = poll_gdsc_status(sc, DISABLED); if (ret) dev_err(&rdev->dev, "%s disable timed out: 0x%x\n", Loading Loading @@ -434,6 +481,9 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode) mb(); udelay(1); if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, ENABLED); else ret = poll_gdsc_status(sc, ENABLED); if (ret) dev_err(&rdev->dev, "%s set_mode timed out: 0x%x\n", Loading Loading @@ -531,6 +581,9 @@ static int gdsc_probe(struct platform_device *pdev) return -ENODEV; } sc->poll_cfg_gdscr = of_property_read_bool(pdev->dev.of_node, "qcom,poll-cfg-gdscr"); sc->gds_timeout = TIMEOUT_US; ret = of_property_read_u32(pdev->dev.of_node, "qcom,gds-timeout", Loading Loading @@ -667,6 +720,9 @@ static int gdsc_probe(struct platform_device *pdev) regval &= ~SW_COLLAPSE_MASK; regmap_write(sc->regmap, REG_OFFSET, regval); if (sc->poll_cfg_gdscr) ret = poll_cfg_gdsc_status(sc, ENABLED); else ret = poll_gdsc_status(sc, ENABLED); if (ret) { dev_err(&pdev->dev, "%s enable timed out: 0x%x\n", Loading