struct regulator_bulk_data supplies[2];
        struct gpio_desc *gpio_reset;
        struct gpio_desc *gpio_powerdown;
+       bool powered;
 };
 
 static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e)
        return 0;
 }
 
-static void ps8640_pre_enable(struct drm_bridge *bridge)
+static void ps8640_bridge_poweron(struct ps8640 *ps_bridge)
 {
-       struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
        struct i2c_client *client = ps_bridge->page[PAGE2_TOP_CNTL];
        unsigned long timeout;
        int ret, status;
 
+       if (ps_bridge->powered)
+               return;
+
        ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies),
                                    ps_bridge->supplies);
        if (ret < 0) {
                goto err_regulators_disable;
        }
 
-       ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
-       if (ret)
-               goto err_regulators_disable;
-
        /* Switch access edp panel's edid through i2c */
        ret = i2c_smbus_write_byte_data(client, PAGE2_I2C_BYPASS,
                                        I2C_BYPASS_EN);
                goto err_regulators_disable;
        }
 
+       ps_bridge->powered = true;
+
        return;
 
 err_regulators_disable:
                               ps_bridge->supplies);
 }
 
-static void ps8640_post_disable(struct drm_bridge *bridge)
+static void ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
 {
-       struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
        int ret;
 
-       ps8640_bridge_vdo_control(ps_bridge, DISABLE);
+       if (!ps_bridge->powered)
+               return;
 
        gpiod_set_value(ps_bridge->gpio_reset, 1);
        gpiod_set_value(ps_bridge->gpio_powerdown, 1);
                                     ps_bridge->supplies);
        if (ret < 0)
                DRM_ERROR("cannot disable regulators %d\n", ret);
+
+       ps_bridge->powered = false;
+}
+
+static void ps8640_pre_enable(struct drm_bridge *bridge)
+{
+       struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
+       int ret;
+
+       ps8640_bridge_poweron(ps_bridge);
+
+       ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
+       if (ret < 0)
+               ps8640_bridge_poweroff(ps_bridge);
+}
+
+static void ps8640_post_disable(struct drm_bridge *bridge)
+{
+       struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
+
+       ps8640_bridge_vdo_control(ps_bridge, DISABLE);
+       ps8640_bridge_poweroff(ps_bridge);
 }
 
 static int ps8640_bridge_attach(struct drm_bridge *bridge,
                                           struct drm_connector *connector)
 {
        struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
+       bool poweroff = !ps_bridge->powered;
+       struct edid *edid;
+
+       /*
+        * When we end calling get_edid() triggered by an ioctl, i.e
+        *
+        *   drm_mode_getconnector (ioctl)
+        *     -> drm_helper_probe_single_connector_modes
+        *        -> drm_bridge_connector_get_modes
+        *           -> ps8640_bridge_get_edid
+        *
+        * We need to make sure that what we need is enabled before reading
+        * EDID, for this chip, we need to do a full poweron, otherwise it will
+        * fail.
+        */
+       drm_bridge_chain_pre_enable(bridge);
 
-       return drm_get_edid(connector,
+       edid = drm_get_edid(connector,
                            ps_bridge->page[PAGE0_DP_CNTL]->adapter);
+
+       /*
+        * If we call the get_edid() function without having enabled the chip
+        * before, return the chip to its original power state.
+        */
+       if (poweroff)
+               drm_bridge_chain_post_disable(bridge);
+
+       return edid;
 }
 
 static const struct drm_bridge_funcs ps8640_bridge_funcs = {