Message ID | 20190316154801.20460-4-jacopo+renesas@jmondi.org (mailing list archive) |
---|---|
State | New |
Delegated to: | Kieran Bingham |
Headers | show |
Series | media: Implement negotiation of CSI-2 data lanes | expand |
Hi Jacopo, On 16/03/2019 15:47, Jacopo Mondi wrote: > Use the TXA routing information to configure the number of active CSI-2 > data lanes. When routing AFE through TXA limit the number of data lanes > to 1, while in the canonical HDMI->TXA routing use all the physically > available ones. > > The number of lanes collected from the 'data-lanes' DT property is now > used as a the number of physically available data lanes, while the > 'num_lanes' variable contains the number of active ones. Could the variable perhaps be called active_lanes rather than num_lanes if it represents how many are active rather than how many there are? > > Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> > --- > drivers/media/i2c/adv748x/adv748x-core.c | 19 ++++++++++++++++++- > drivers/media/i2c/adv748x/adv748x.h | 1 + > 2 files changed, 19 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c > index 02135741b1a6..f91c7b83f1bf 100644 > --- a/drivers/media/i2c/adv748x/adv748x-core.c > +++ b/drivers/media/i2c/adv748x/adv748x-core.c > @@ -350,6 +350,8 @@ static int adv748x_link_setup(struct media_entity *entity, > struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); > bool enable = flags & MEDIA_LNK_FL_ENABLED; > u8 csi4_in_sel = 0; > + u8 num_lanes; > + int ret; > > /* Refuse to enable multiple links to the same TX at the same time. */ > if (enable && tx->src) > @@ -373,10 +375,23 @@ static int adv748x_link_setup(struct media_entity *entity, > csi4_in_sel |= ADV748X_IO_10_CSI4_IN_SEL_AFE; > else > csi4_in_sel |= ADV748X_IO_10_CSI1_EN; > + > + num_lanes = 1; > } > > - if (state->hdmi.tx) > + if (state->hdmi.tx) { > csi4_in_sel |= ADV748X_IO_10_CSI4_EN; > + num_lanes = tx->available_lanes; > + } > + > + /* Update the number of active lanes if it has changed. */ > + if (num_lanes != tx->num_lanes) { > + tx->num_lanes = num_lanes; > + ret = adv748x_write(state, tx->page, 0x00, > + 0x80 | tx->num_lanes); > + if (ret) > + return ret; > + } > > state->csi4_in_sel = csi4_in_sel; > > @@ -608,6 +623,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, > } > > state->txa.num_lanes = num_lanes; > + state->txa.available_lanes = num_lanes; > adv_dbg(state, "TXA: using %u lanes\n", state->txa.num_lanes); > } > > @@ -619,6 +635,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, > } > > state->txb.num_lanes = num_lanes; > + state->txb.available_lanes = num_lanes; > adv_dbg(state, "TXB: using %u lanes\n", state->txb.num_lanes); > } > > diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h > index 27c116d09284..6e5c2cb421fe 100644 > --- a/drivers/media/i2c/adv748x/adv748x.h > +++ b/drivers/media/i2c/adv748x/adv748x.h > @@ -80,6 +80,7 @@ struct adv748x_csi2 { > unsigned int page; > unsigned int port; > unsigned int num_lanes; Aha, except num_lanes looks like its' from an earlier patch... I wonder if it's worth renaming... > + unsigned int available_lanes; > > struct media_pad pads[ADV748X_CSI2_NR_PADS]; > struct v4l2_ctrl_handler ctrl_hdl; >
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c index 02135741b1a6..f91c7b83f1bf 100644 --- a/drivers/media/i2c/adv748x/adv748x-core.c +++ b/drivers/media/i2c/adv748x/adv748x-core.c @@ -350,6 +350,8 @@ static int adv748x_link_setup(struct media_entity *entity, struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); bool enable = flags & MEDIA_LNK_FL_ENABLED; u8 csi4_in_sel = 0; + u8 num_lanes; + int ret; /* Refuse to enable multiple links to the same TX at the same time. */ if (enable && tx->src) @@ -373,10 +375,23 @@ static int adv748x_link_setup(struct media_entity *entity, csi4_in_sel |= ADV748X_IO_10_CSI4_IN_SEL_AFE; else csi4_in_sel |= ADV748X_IO_10_CSI1_EN; + + num_lanes = 1; } - if (state->hdmi.tx) + if (state->hdmi.tx) { csi4_in_sel |= ADV748X_IO_10_CSI4_EN; + num_lanes = tx->available_lanes; + } + + /* Update the number of active lanes if it has changed. */ + if (num_lanes != tx->num_lanes) { + tx->num_lanes = num_lanes; + ret = adv748x_write(state, tx->page, 0x00, + 0x80 | tx->num_lanes); + if (ret) + return ret; + } state->csi4_in_sel = csi4_in_sel; @@ -608,6 +623,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, } state->txa.num_lanes = num_lanes; + state->txa.available_lanes = num_lanes; adv_dbg(state, "TXA: using %u lanes\n", state->txa.num_lanes); } @@ -619,6 +635,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, } state->txb.num_lanes = num_lanes; + state->txb.available_lanes = num_lanes; adv_dbg(state, "TXB: using %u lanes\n", state->txb.num_lanes); } diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 27c116d09284..6e5c2cb421fe 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -80,6 +80,7 @@ struct adv748x_csi2 { unsigned int page; unsigned int port; unsigned int num_lanes; + unsigned int available_lanes; struct media_pad pads[ADV748X_CSI2_NR_PADS]; struct v4l2_ctrl_handler ctrl_hdl;
Use the TXA routing information to configure the number of active CSI-2 data lanes. When routing AFE through TXA limit the number of data lanes to 1, while in the canonical HDMI->TXA routing use all the physically available ones. The number of lanes collected from the 'data-lanes' DT property is now used as a the number of physically available data lanes, while the 'num_lanes' variable contains the number of active ones. Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> --- drivers/media/i2c/adv748x/adv748x-core.c | 19 ++++++++++++++++++- drivers/media/i2c/adv748x/adv748x.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-)