[PATCH V3 2/6] i2c: qup: Add V2 tags support
Sricharan R
sricharan at codeaurora.org
Thu Apr 16 02:39:05 PDT 2015
Hi Ivan,
On 04/16/2015 02:06 PM, Ivan T. Ivanov wrote:
>
> 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?
>
The controller was not supporting this 'no-stop' feature by default
and not sure whether to call it a 'bug' or 'missing feature', which
it supports now anyway. Regarding the internal driver, it was
trying to coalesce the writes (if they are to same address) by
configuring the WR_CNT register to the sum of msg->len of the
consecutive sub-transfers. This is no more needed with this 'feature'.
>
>
> -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?
>
controller itself.
>>>>>> +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.
>
fifo is filled using the same 'flags' in both v1 and v2.
The difference is the way tags and data are assembled in the
output. But as i said, it can be improved atleast in v2 easily
(can be done in v1 also, but is not something required in this
patch) and i will change that in next version.
>>>>>> +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 :-)
>
ok.
Regards,
Sricharan
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a
member of Code Aurora Forum, hosted by The Linux Foundation
More information about the linux-arm-kernel
mailing list