[PATCH V3 2/6] i2c: qup: Add V2 tags support

Ivan T. Ivanov iivanov at mm-sol.com
Thu Apr 16 01:36:35 PDT 2015


Hi Sricharan,

On Wed, 2015-04-15 at 20:14 +0530, Sricharan R wrote:
> 
> > > > > 
> > > > > +#define QUP_I2C_MX_CONFIG_DURING_RUN   BIT(31)
> > > > 
> > > > Could you explain what is this for?
> > > > 
> > >     This is a new feature in the V2 version of the controller,
> > >     to support multiple i2c sub transfers without having
> > >     a 'stop' bit in-between. Without this the i2c controller
> > >     inserts a 'stop' on the bus when the WR/RD count registers
> > >     reaches zero and are configured for the next transfer. So setting
> > >     this bit when the controller is in 'RUN' state, avoids sending the
> > >     'stop' during RUN state.
> > >     I can add this comment in the patch.
> > 
> > And how v2 of this patch was worked if you introduce this bit now?
> > Bit is also not used by downstream driver, AFICS?
> > 
> The one of the reason for this and the bam support patches in
> this series was to support multiple transfers of i2c_msgs without
>   a 'stop' inbetween them. So without that the driver sends a 'stop'
> between each sub-transfer. 

Are you saying that there is bug in the hardware? Please, could you
point me to codeaurora driver, which is using this bit? 



-static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg)
> > > > > +static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg,
> > > > > +                                                       int run)
> > > > 
> > > > And 'run' stands for?
> > >    'run' just says whether the controller is in 'RUN' or 'RESET' state.
> > >     I can change it to is_run_st to make it clear.
> > > > >    {
> > > > > -       /* Number of entries to shift out, including the start */
> > > > > -       int total = msg->len + 1;
> > > > > +       /* Total Number of entries to shift out, including the tags */
> > > > > +       int total;
> > > > > +
> > > > > +       if (qup->use_v2_tags) {
> > > > > +               total = msg->len + qup->tx_tag_len;
> > > > > +               if (run)
> > > > > +                       total |= QUP_I2C_MX_CONFIG_DURING_RUN;
> > > > 
> > > > What?
> > > > 
> > >        This means, if the controller is in 'RUN' state, for
> > >        reconfiguring the RD/WR counts this bit has to be set to avoid
> > >        'stop' bits.
> > 
> > I don't buy it, sorry. Problem with v1 of the tags is that controller
> > can not read more than 256 bytes without automatically generate STOP
> > at the end, because transfer length specified with QUP_TAG_REC tag
> > is 8 bits wide. There is no limitation for writes with v1 tags,
> > because controller is explicitly instructed when to send out STOP.
> > 
> correct till this.
> 
> > For v2 of the tags, writes behaves more or less the same, and the
> > good news are that there is new read tag QUP_TAG_V2_DATARD, which
> > did't generate STOP when specified amount of data is read, still
> > up to 256 bytes in chunk. Read transfers with size more than 256
> > could be formed in following way:
> > 
> > V2_START | Slave Address | V2_DATARD | countx | ... | V2_DATARD_STOP | county.
> > 
>   The above is true for a single subtransfer for reading/writing
> more than > 256 bytes. But for doing WRITE, READ kind of sub
>   transfers once the first sub transfer (write) is over, and
>   while re-configuring the _COUNT registers for the next transfers,
> 'a stop' between is inserted.

>From controller itself or driver?

> > > > > +static void qup_i2c_issue_xfer_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
> > > > > +{
> > > > > +       u32 data_len = 0, tag_len;
> > > > > +
> > > > > +       tag_len = qup->blk.block_tag_len[qup->blk.block_pos];
> > > > > +
> > > > > +       if (!(msg->flags & I2C_M_RD))
> > > > > +               data_len = qup->blk.block_data_len[qup->blk.block_pos];
> > > > > +
> > > > > +       qup_i2c_send_data(qup, tag_len, qup->tags, data_len, msg->buf);
> > > > 
> > > > This assumes that writes are up to 256 bytes, and tags and data blocks
> > > > are completely written to FIFO buffer, right?
> > > > 
> > >    Yes, since we send/read data in blocks (256 bytes).
> > 
> > How deep is the FIFO? Is it guaranteed that "the whole" write
> > or read data, including tags will fit in.
> > 
>   Write/read fifo functions (also for V1) currently wait for the
>    fifo full and empty flags conditions.

I will say that this is true for v1, but not for v2, 
because the way of how FIFO is filled in v2.

> > > > > +static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg,
> > > > > +                                                               int run, int last)
> > > > >    {
> > > > >           unsigned long left;
> > > > >           int ret;
> > > > > @@ -329,13 +501,20 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct 
> > > > > i2c_msg *msg)
> > > > >           qup->msg = msg;
> > > > >           qup->pos = 0;
> > > > > 
> > > > > +       if (qup->use_v2_tags)
> > > > > +               qup_i2c_create_tag_v2(qup, msg, last);
> > > > > +       else
> > > > > +               qup->blk.blocks = 0;
> > > > > +
> > > > >           enable_irq(qup->irq);
> > > > > 
> > > > > -       qup_i2c_set_write_mode(qup, msg);
> > > > > +       qup_i2c_set_write_mode(qup, msg, run);
> > > > > 
> > > > > -       ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
> > > > > -       if (ret)
> > > > > -               goto err;
> > > > > +       if (!run) {
> > > > > +               ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
> > > > 
> > > > To run away, or not?
> > > > 
> > >     Means, if the controller is not in RUN state, put it in to 'RUN'
> > >     state.
> > 
> > And what is the problem if controller is put in PAUSED state, FIFO
> > filled with data and then RUN again, like in v2 of this patch?
> > 
>   This function is not entered with controller in PAUSED state
>   Only in Reset state (for the first transfer) and Run state for
>   the subsequent sub-transfers. The reason for having this 'run'
>   variable was that while using the lock-unlock feature, the
>   controller should not be put in to run-reset-run state
>   in-between transfers.

Lets see how it will look, when new qup_i2c_write_one_v2 is introduced :-)

Ivan




More information about the linux-arm-kernel mailing list