diff mbox series

[v2,2/2] drm/bridge: anx7625: disable regulators when power off

Message ID 20201123034652.3660584-2-hsinyi@chromium.org
State New
Headers show
Series [v2,1/2] dt-bindings: drm/bridge: anx7625: Add power supplies | expand

Commit Message

Hsin-Yi Wang Nov. 23, 2020, 3:46 a.m. UTC
When suspending the driver, anx7625_power_standby() will be called to
turn off reset-gpios and enable-gpios. However, power supplies are not
disabled. To save power, the driver can get the power supply regulators
and turn off them in anx7625_power_standby().

Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
---
Change:
v2: none
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 25 +++++++++++++++++++++++
 drivers/gpu/drm/bridge/analogix/anx7625.h |  1 +
 2 files changed, 26 insertions(+)

Comments

Hsin-Yi Wang Dec. 9, 2020, 4:43 a.m. UTC | #1
On Mon, Nov 23, 2020 at 11:47 AM Hsin-Yi Wang <hsinyi@chromium.org> wrote:
>

> When suspending the driver, anx7625_power_standby() will be called to

> turn off reset-gpios and enable-gpios. However, power supplies are not

> disabled. To save power, the driver can get the power supply regulators

> and turn off them in anx7625_power_standby().

>

> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>


Gentle ping on the patch

> ---

> Change:

> v2: none

> ---

>  drivers/gpu/drm/bridge/analogix/anx7625.c | 25 +++++++++++++++++++++++

>  drivers/gpu/drm/bridge/analogix/anx7625.h |  1 +

>  2 files changed, 26 insertions(+)

>

> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c

> index 65cc05982f82..eb9c4cc2504a 100644

> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c

> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c

> @@ -11,6 +11,7 @@

>  #include <linux/kernel.h>

>  #include <linux/module.h>

>  #include <linux/mutex.h>

> +#include <linux/regulator/consumer.h>

>  #include <linux/slab.h>

>  #include <linux/types.h>

>  #include <linux/workqueue.h>

> @@ -875,12 +876,20 @@ static int sp_tx_edid_read(struct anx7625_data *ctx,

>  static void anx7625_power_on(struct anx7625_data *ctx)

>  {

>         struct device *dev = &ctx->client->dev;

> +       int ret;

>

>         if (!ctx->pdata.low_power_mode) {

>                 DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n");

>                 return;

>         }

>

> +       ret = regulator_bulk_enable(ARRAY_SIZE(ctx->pdata.supplies),

> +                                   ctx->pdata.supplies);

> +       if (ret < 0) {

> +               DRM_DEV_DEBUG_DRIVER(dev, "cannot enable regulators %d\n", ret);

> +               return;

> +       }

> +

>         /* Power on pin enable */

>         gpiod_set_value(ctx->pdata.gpio_p_on, 1);

>         usleep_range(10000, 11000);

> @@ -894,6 +903,7 @@ static void anx7625_power_on(struct anx7625_data *ctx)

>  static void anx7625_power_standby(struct anx7625_data *ctx)

>  {

>         struct device *dev = &ctx->client->dev;

> +       int ret;

>

>         if (!ctx->pdata.low_power_mode) {

>                 DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n");

> @@ -904,6 +914,12 @@ static void anx7625_power_standby(struct anx7625_data *ctx)

>         usleep_range(1000, 1100);

>         gpiod_set_value(ctx->pdata.gpio_p_on, 0);

>         usleep_range(1000, 1100);

> +

> +       ret = regulator_bulk_disable(ARRAY_SIZE(ctx->pdata.supplies),

> +                                    ctx->pdata.supplies);

> +       if (ret < 0)

> +               DRM_DEV_DEBUG_DRIVER(dev, "cannot disable regulators %d\n", ret);

> +

>         DRM_DEV_DEBUG_DRIVER(dev, "power down\n");

>  }

>

> @@ -1742,6 +1758,15 @@ static int anx7625_i2c_probe(struct i2c_client *client,

>         platform->client = client;

>         i2c_set_clientdata(client, platform);

>

> +       pdata->supplies[0].supply = "vdd10";

> +       pdata->supplies[1].supply = "vdd18";

> +       pdata->supplies[2].supply = "vdd33";

> +       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pdata->supplies),

> +                                     pdata->supplies);

> +       if (ret) {

> +               DRM_DEV_ERROR(dev, "fail to get power supplies: %d\n", ret);

> +               return ret;

> +       }

>         anx7625_init_gpio(platform);

>

>         atomic_set(&platform->power_status, 0);

> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h

> index 193ad86c5450..e4a086b3a3d7 100644

> --- a/drivers/gpu/drm/bridge/analogix/anx7625.h

> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h

> @@ -350,6 +350,7 @@ struct s_edid_data {

>  struct anx7625_platform_data {

>         struct gpio_desc *gpio_p_on;

>         struct gpio_desc *gpio_reset;

> +       struct regulator_bulk_data supplies[3];

>         struct drm_bridge *panel_bridge;

>         int intp_irq;

>         u32 low_power_mode;

> --

> 2.29.2.454.gaff20da3a2-goog

>
Hsin-Yi Wang Dec. 25, 2020, 5:41 a.m. UTC | #2
On Wed, Dec 9, 2020 at 12:43 PM Hsin-Yi Wang <hsinyi@chromium.org> wrote:
>

> On Mon, Nov 23, 2020 at 11:47 AM Hsin-Yi Wang <hsinyi@chromium.org> wrote:

> >

> > When suspending the driver, anx7625_power_standby() will be called to

> > turn off reset-gpios and enable-gpios. However, power supplies are not

> > disabled. To save power, the driver can get the power supply regulators

> > and turn off them in anx7625_power_standby().

> >

> > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>

>

> Gentle ping on the patch

>


After some testing, the powering sequence has some issue and would
cause i2c failures. The powering sequence needs to be rechecked.

> > ---

> > Change:

> > v2: none

> > ---

> >  drivers/gpu/drm/bridge/analogix/anx7625.c | 25 +++++++++++++++++++++++

> >  drivers/gpu/drm/bridge/analogix/anx7625.h |  1 +

> >  2 files changed, 26 insertions(+)

> >

> > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c

> > index 65cc05982f82..eb9c4cc2504a 100644

> > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c

> > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c

> > @@ -11,6 +11,7 @@

> >  #include <linux/kernel.h>

> >  #include <linux/module.h>

> >  #include <linux/mutex.h>

> > +#include <linux/regulator/consumer.h>

> >  #include <linux/slab.h>

> >  #include <linux/types.h>

> >  #include <linux/workqueue.h>

> > @@ -875,12 +876,20 @@ static int sp_tx_edid_read(struct anx7625_data *ctx,

> >  static void anx7625_power_on(struct anx7625_data *ctx)

> >  {

> >         struct device *dev = &ctx->client->dev;

> > +       int ret;

> >

> >         if (!ctx->pdata.low_power_mode) {

> >                 DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n");

> >                 return;

> >         }

> >

> > +       ret = regulator_bulk_enable(ARRAY_SIZE(ctx->pdata.supplies),

> > +                                   ctx->pdata.supplies);

> > +       if (ret < 0) {

> > +               DRM_DEV_DEBUG_DRIVER(dev, "cannot enable regulators %d\n", ret);

> > +               return;

> > +       }

> > +

> >         /* Power on pin enable */

> >         gpiod_set_value(ctx->pdata.gpio_p_on, 1);

> >         usleep_range(10000, 11000);

> > @@ -894,6 +903,7 @@ static void anx7625_power_on(struct anx7625_data *ctx)

> >  static void anx7625_power_standby(struct anx7625_data *ctx)

> >  {

> >         struct device *dev = &ctx->client->dev;

> > +       int ret;

> >

> >         if (!ctx->pdata.low_power_mode) {

> >                 DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n");

> > @@ -904,6 +914,12 @@ static void anx7625_power_standby(struct anx7625_data *ctx)

> >         usleep_range(1000, 1100);

> >         gpiod_set_value(ctx->pdata.gpio_p_on, 0);

> >         usleep_range(1000, 1100);

> > +

> > +       ret = regulator_bulk_disable(ARRAY_SIZE(ctx->pdata.supplies),

> > +                                    ctx->pdata.supplies);

> > +       if (ret < 0)

> > +               DRM_DEV_DEBUG_DRIVER(dev, "cannot disable regulators %d\n", ret);

> > +

> >         DRM_DEV_DEBUG_DRIVER(dev, "power down\n");

> >  }

> >

> > @@ -1742,6 +1758,15 @@ static int anx7625_i2c_probe(struct i2c_client *client,

> >         platform->client = client;

> >         i2c_set_clientdata(client, platform);

> >

> > +       pdata->supplies[0].supply = "vdd10";

> > +       pdata->supplies[1].supply = "vdd18";

> > +       pdata->supplies[2].supply = "vdd33";

> > +       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pdata->supplies),

> > +                                     pdata->supplies);

> > +       if (ret) {

> > +               DRM_DEV_ERROR(dev, "fail to get power supplies: %d\n", ret);

> > +               return ret;

> > +       }

> >         anx7625_init_gpio(platform);

> >

> >         atomic_set(&platform->power_status, 0);

> > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h

> > index 193ad86c5450..e4a086b3a3d7 100644

> > --- a/drivers/gpu/drm/bridge/analogix/anx7625.h

> > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h

> > @@ -350,6 +350,7 @@ struct s_edid_data {

> >  struct anx7625_platform_data {

> >         struct gpio_desc *gpio_p_on;

> >         struct gpio_desc *gpio_reset;

> > +       struct regulator_bulk_data supplies[3];

> >         struct drm_bridge *panel_bridge;

> >         int intp_irq;

> >         u32 low_power_mode;

> > --

> > 2.29.2.454.gaff20da3a2-goog

> >
diff mbox series

Patch

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 65cc05982f82..eb9c4cc2504a 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -11,6 +11,7 @@ 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
@@ -875,12 +876,20 @@  static int sp_tx_edid_read(struct anx7625_data *ctx,
 static void anx7625_power_on(struct anx7625_data *ctx)
 {
 	struct device *dev = &ctx->client->dev;
+	int ret;
 
 	if (!ctx->pdata.low_power_mode) {
 		DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n");
 		return;
 	}
 
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->pdata.supplies),
+				    ctx->pdata.supplies);
+	if (ret < 0) {
+		DRM_DEV_DEBUG_DRIVER(dev, "cannot enable regulators %d\n", ret);
+		return;
+	}
+
 	/* Power on pin enable */
 	gpiod_set_value(ctx->pdata.gpio_p_on, 1);
 	usleep_range(10000, 11000);
@@ -894,6 +903,7 @@  static void anx7625_power_on(struct anx7625_data *ctx)
 static void anx7625_power_standby(struct anx7625_data *ctx)
 {
 	struct device *dev = &ctx->client->dev;
+	int ret;
 
 	if (!ctx->pdata.low_power_mode) {
 		DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n");
@@ -904,6 +914,12 @@  static void anx7625_power_standby(struct anx7625_data *ctx)
 	usleep_range(1000, 1100);
 	gpiod_set_value(ctx->pdata.gpio_p_on, 0);
 	usleep_range(1000, 1100);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->pdata.supplies),
+				     ctx->pdata.supplies);
+	if (ret < 0)
+		DRM_DEV_DEBUG_DRIVER(dev, "cannot disable regulators %d\n", ret);
+
 	DRM_DEV_DEBUG_DRIVER(dev, "power down\n");
 }
 
@@ -1742,6 +1758,15 @@  static int anx7625_i2c_probe(struct i2c_client *client,
 	platform->client = client;
 	i2c_set_clientdata(client, platform);
 
+	pdata->supplies[0].supply = "vdd10";
+	pdata->supplies[1].supply = "vdd18";
+	pdata->supplies[2].supply = "vdd33";
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pdata->supplies),
+				      pdata->supplies);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "fail to get power supplies: %d\n", ret);
+		return ret;
+	}
 	anx7625_init_gpio(platform);
 
 	atomic_set(&platform->power_status, 0);
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h
index 193ad86c5450..e4a086b3a3d7 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.h
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.h
@@ -350,6 +350,7 @@  struct s_edid_data {
 struct anx7625_platform_data {
 	struct gpio_desc *gpio_p_on;
 	struct gpio_desc *gpio_reset;
+	struct regulator_bulk_data supplies[3];
 	struct drm_bridge *panel_bridge;
 	int intp_irq;
 	u32 low_power_mode;