Hi Alex. On Mon, Oct 19, 2020 at 08:24:40PM -0500, Alex G. wrote: > On 9/28/20 12:30 PM, Alexandru Gagniuc wrote: > > 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@xxxxxxxxx> > > --- > > Changes since v1: > > * Fix return code after regulator_enable(sii902x->iovcc) fails (Fabio Estevam) > > * Use dev_err_probe() instead of dev_err() where appropriate (Sam Ravnborg) > > > > drivers/gpu/drm/bridge/sii902x.c | 54 ++++++++++++++++++++++++++++---- > > 1 file changed, 48 insertions(+), 6 deletions(-) > > This patch seems to have entered fall dormancy. Did I miss somebody in the > CC field? I have lost the original mail/patch. Can you resend with one fix - see below. Sam > > Alex > > > > diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c > > index 33fd33f953ec..d15e9f2c0d8a 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,8 @@ struct sii902x { > > struct drm_connector connector; > > struct gpio_desc *reset_gpio; > > struct i2c_mux_core *i2cmux; > > + struct regulator *iovcc; > > + struct regulator *cvcc12; > > /* > > * Mutex protects audio and video functions from interfering > > * each other, by keeping their i2c command sequences atomic. > > @@ -954,13 +957,13 @@ static const struct drm_bridge_timings default_sii902x_timings = { > > | DRM_BUS_FLAG_DE_HIGH, > > }; > > +static int sii902x_init(struct sii902x *sii902x); Please re-arrange the code so this prototype is not needed. > > + > > static int sii902x_probe(struct i2c_client *client, > > const struct i2c_device_id *id) > > { > > struct device *dev = &client->dev; > > - unsigned int status = 0; > > struct sii902x *sii902x; > > - u8 chipid[4]; > > int ret; > > ret = i2c_check_functionality(client->adapter, > > @@ -989,6 +992,43 @@ static int sii902x_probe(struct i2c_client *client, > > mutex_init(&sii902x->mutex); > > + sii902x->iovcc = devm_regulator_get(dev, "iovcc"); > > + if (IS_ERR(sii902x->iovcc)) > > + return PTR_ERR(sii902x->iovcc); > > + > > + sii902x->cvcc12 = devm_regulator_get(dev, "cvcc12"); > > + if (IS_ERR(sii902x->cvcc12)) > > + return PTR_ERR(sii902x->cvcc12); > > + > > + ret = regulator_enable(sii902x->iovcc); > > + if (ret < 0) { > > + dev_err_probe(dev, ret, "Failed to enable iovcc supply"); > > + return ret; > > + } > > + > > + ret = regulator_enable(sii902x->cvcc12); > > + if (ret < 0) { > > + dev_err_probe(dev, ret, "Failed to enable cvcc12 supply"); > > + regulator_disable(sii902x->iovcc); > > + return ret; > > + } > > + > > + ret = sii902x_init(sii902x); > > + if (ret < 0) { > > + regulator_disable(sii902x->cvcc12); > > + regulator_disable(sii902x->iovcc); > > + } > > + > > + return ret; > > +} > > + > > +static int sii902x_init(struct sii902x *sii902x) > > +{ > > + struct device *dev = &sii902x->i2c->dev; > > + unsigned int status = 0; > > + u8 chipid[4]; > > + int ret; > > + > > sii902x_reset(sii902x); > > ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0); > > @@ -1012,11 +1052,11 @@ static int sii902x_probe(struct i2c_client *client, > > regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status); > > regmap_write(sii902x->regmap, SII902X_INT_STATUS, status); > > - if (client->irq > 0) { > > + if (sii902x->i2c->irq > 0) { > > regmap_write(sii902x->regmap, SII902X_INT_ENABLE, > > SII902X_HOTPLUG_EVENT); > > - ret = devm_request_threaded_irq(dev, client->irq, NULL, > > + ret = devm_request_threaded_irq(dev, sii902x->i2c->irq, NULL, > > sii902x_interrupt, > > IRQF_ONESHOT, dev_name(dev), > > sii902x); > > @@ -1031,9 +1071,9 @@ static int sii902x_probe(struct i2c_client *client, > > sii902x_audio_codec_init(sii902x, dev); > > - i2c_set_clientdata(client, sii902x); > > + i2c_set_clientdata(sii902x->i2c, sii902x); > > - sii902x->i2cmux = i2c_mux_alloc(client->adapter, dev, > > + sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev, > > 1, 0, I2C_MUX_GATE, > > sii902x_i2c_bypass_select, > > sii902x_i2c_bypass_deselect); > > @@ -1051,6 +1091,8 @@ static int sii902x_remove(struct i2c_client *client) > > i2c_mux_del_adapters(sii902x->i2cmux); > > drm_bridge_remove(&sii902x->bridge); > > + regulator_disable(sii902x->cvcc12); > > + regulator_disable(sii902x->iovcc); > > return 0; > > } > > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/dri-devel