summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlexandru Gagniuc <mr.nuke.me@gmail.com>2020-10-21 01:14:58 +0300
committerSam Ravnborg <sam@ravnborg.org>2020-11-08 13:53:37 +0300
commitcc5f7e2fcbe396f2f461cd67c872af771a334bca (patch)
treee0c5ec3a5df80e87cdc582d8236cc1ed6ade2a4b /drivers/gpu
parent4c1e054322da99cbfd293a5fddf283f2fdb3e2d0 (diff)
downloadlinux-cc5f7e2fcbe396f2f461cd67c872af771a334bca.tar.xz
drm/bridge: sii902x: Enable I/O and core VCC supplies if present
On the SII9022, the IOVCC and CVCC12 supplies must reach the correct voltage before the reset sequence is initiated. On most boards, this assumption is true at boot-up, so initialization succeeds. However, when we try to initialize the chip with incorrect supply voltages, it will not respond to I2C requests. sii902x_probe() fails with -ENXIO. To resolve this, look for the "iovcc" and "cvcc12" regulators, and make sure they are enabled before starting the reset sequence. If these supplies are not available in devicetree, then they will default to dummy-regulator. In that case everything will work like before. This was observed on a STM32MP157C-DK2 booting in u-boot falcon mode. On this board, the supplies would be set by the second stage bootloader, which does not run in falcon mode. Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org> [Fix checkpatch warnings] Link: https://patchwork.freedesktop.org/patch/msgid/20201020221501.260025-2-mr.nuke.me@gmail.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index f78c17f49887..89558e581530 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#include <drm/drm_atomic_helper.h>
@@ -168,6 +169,7 @@ struct sii902x {
struct drm_connector connector;
struct gpio_desc *reset_gpio;
struct i2c_mux_core *i2cmux;
+ struct regulator_bulk_data supplies[2];
/*
* Mutex protects audio and video functions from interfering
* each other, by keeping their i2c command sequences atomic.
@@ -1049,7 +1051,26 @@ static int sii902x_probe(struct i2c_client *client,
mutex_init(&sii902x->mutex);
+ sii902x->supplies[0].supply = "iovcc";
+ sii902x->supplies[1].supply = "cvcc12";
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sii902x->supplies),
+ sii902x->supplies);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(sii902x->supplies),
+ sii902x->supplies);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "Failed to enable supplies");
+ return ret;
+ }
+
ret = sii902x_init(sii902x);
+ if (ret < 0) {
+ regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
+ sii902x->supplies);
+ }
+
return ret;
}
@@ -1060,6 +1081,8 @@ static int sii902x_remove(struct i2c_client *client)
i2c_mux_del_adapters(sii902x->i2cmux);
drm_bridge_remove(&sii902x->bridge);
+ regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
+ sii902x->supplies);
return 0;
}