Message ID | 1447047839-5223-3-git-send-email-liguo.zhang@mediatek.com |
---|---|
State | Changes Requested |
Headers | show |
On Mon, Nov 9, 2015 at 1:43 PM, Liguo Zhang <liguo.zhang@mediatek.com> wrote: > For platform with auto restart support, when doing i2c multi transfer > in high speed, for example, doing write-then-read transfer, the master > code will occupy the first transfer, and the second transfer will be > the read transfer, the write transfer will be discarded. So we should > first send the master code, and then start i2c multi transfer. > > Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com> > Reviewed-by: Eddie Huang <eddie.huang@mediatek.com> > --- > drivers/i2c/busses/i2c-mt65xx.c | 45 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 45 insertions(+) > > diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c > index dc4aac6..249df86 100644 > --- a/drivers/i2c/busses/i2c-mt65xx.c > +++ b/drivers/i2c/busses/i2c-mt65xx.c > @@ -53,6 +53,8 @@ > #define I2C_FS_TIME_INIT_VALUE 0x1303 > #define I2C_WRRD_TRANAC_VALUE 0x0002 > #define I2C_RD_TRANAC_VALUE 0x0001 > +#define I2C_TRAN_DEFAULT_VALUE 0x0001 > +#define I2C_TRANAC_DEFAULT_VALUE 0x0001 "TRAN" and "TRANAC" are not good names; this should be "TRANSFER_LEN" and "TRANSAC", based on the names of the registers to which you write these constants. Furthermore, these are not "default" values, they are the transfer length and number of transactions for sending the "master code", so: #define I2C_TRANSFER_LEN_MASTER_CODE 0x0001 #define I2C_TRANSAC_LEN_MASTER_CODE 0x0001 Similarly, I think the "TRANAC" in I2C_WRRD_TRANAC_VALUE and I2C_RD_TRANAC_VALUE should also be TRANSAC. > > #define I2C_DMA_CON_TX 0x0000 > #define I2C_DMA_CON_RX 0x0001 > @@ -365,6 +367,43 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk, > return 0; > } > > +static int mtk_i2c_send_master_code(struct mtk_i2c *i2c) > +{ > + int ret = 0; > + > + reinit_completion(&i2c->msg_complete); > + > + writew(I2C_CONTROL_RS | I2C_CONTROL_ACKERR_DET_EN | > + I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN, > + i2c->base + OFFSET_CONTROL); > + > + /* Clear interrupt status */ > + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP | I2C_HS_NACKERR | I2C_ACKERR, > + i2c->base + OFFSET_INTR_STAT); > + > + /* Enable interrupt */ > + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP, i2c->base + > + OFFSET_INTR_MASK); > + > + writew(I2C_TRAN_DEFAULT_VALUE, i2c->base + OFFSET_TRANSFER_LEN); > + writew(I2C_TRANAC_DEFAULT_VALUE, i2c->base + OFFSET_TRANSAC_LEN); > + > + writew(I2C_TRANSAC_START | I2C_RS_MUL_CNFG, i2c->base + OFFSET_START); > + > + ret = wait_for_completion_timeout(&i2c->msg_complete, > + i2c->adap.timeout); How does the hardware know that this transaction should be a "master code"? Do you have to tell the hardware what value ('00001XXX') to use as the master code? The Master Code must be sent at <= 400 kHz, not the target clock. How does the hardware know what rate to use? When sending the master code, arbitration is supposed to occur, such that only one winning master can proceed with the following high speed transaction. Where do you check that you won this arbitration? If this is not implemented, adding a "TODO" would be helpful. > + > + completion_done(&i2c->msg_complete); This completion_done() is only useful if you check the return value. You should check it too, since we should only check for timeout if the message hasn't completed. > + > + if (ret == 0) { > + dev_dbg(i2c->dev, "send master code timeout.\n"); > + mtk_i2c_init_hw(i2c); > + return -ETIMEDOUT; > + } > + > + return 0; > +} > + > static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, > int num, int left_num) > { > @@ -539,6 +578,12 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, > } > } > > + if (i2c->auto_restart && i2c->speed_hz > 400000) { Don't we need to send the master code for *every* HS transaction, not just "auto_restart"? "400000" => You already have a macro for this: MAX_FS_MODE_SPEED > + ret = mtk_i2c_send_master_code(i2c); > + if (ret) > + return ret; > + } > + > while (left_num--) { > if (!msgs->buf) { > dev_dbg(i2c->dev, "data buffer is NULL.\n"); > -- > 1.8.1.1.dirty > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Nov 14, 2015 at 10:38:42PM +0800, Daniel Kurtz wrote: > On Mon, Nov 9, 2015 at 1:43 PM, Liguo Zhang <liguo.zhang@mediatek.com> wrote: > > For platform with auto restart support, when doing i2c multi transfer > > in high speed, for example, doing write-then-read transfer, the master > > code will occupy the first transfer, and the second transfer will be > > the read transfer, the write transfer will be discarded. So we should > > first send the master code, and then start i2c multi transfer. > > > > Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com> > > Reviewed-by: Eddie Huang <eddie.huang@mediatek.com> > > --- > > drivers/i2c/busses/i2c-mt65xx.c | 45 +++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 45 insertions(+) > > > > diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c > > index dc4aac6..249df86 100644 > > --- a/drivers/i2c/busses/i2c-mt65xx.c > > +++ b/drivers/i2c/busses/i2c-mt65xx.c > > @@ -53,6 +53,8 @@ > > #define I2C_FS_TIME_INIT_VALUE 0x1303 > > #define I2C_WRRD_TRANAC_VALUE 0x0002 > > #define I2C_RD_TRANAC_VALUE 0x0001 > > +#define I2C_TRAN_DEFAULT_VALUE 0x0001 > > +#define I2C_TRANAC_DEFAULT_VALUE 0x0001 > > "TRAN" and "TRANAC" are not good names; this should be "TRANSFER_LEN" > and "TRANSAC", based on the names of the registers to which you write > these constants. > > Furthermore, these are not "default" values, they are the transfer > length and number of transactions for sending the "master code", so: > > #define I2C_TRANSFER_LEN_MASTER_CODE 0x0001 > #define I2C_TRANSAC_LEN_MASTER_CODE 0x0001 > > Similarly, I think the "TRANAC" in I2C_WRRD_TRANAC_VALUE and > I2C_RD_TRANAC_VALUE should also be TRANSAC. > > > > > #define I2C_DMA_CON_TX 0x0000 > > #define I2C_DMA_CON_RX 0x0001 > > @@ -365,6 +367,43 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk, > > return 0; > > } > > > > +static int mtk_i2c_send_master_code(struct mtk_i2c *i2c) > > +{ > > + int ret = 0; > > + > > + reinit_completion(&i2c->msg_complete); > > + > > + writew(I2C_CONTROL_RS | I2C_CONTROL_ACKERR_DET_EN | > > + I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN, > > + i2c->base + OFFSET_CONTROL); > > + > > + /* Clear interrupt status */ > > + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP | I2C_HS_NACKERR | I2C_ACKERR, > > + i2c->base + OFFSET_INTR_STAT); > > + > > + /* Enable interrupt */ > > + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP, i2c->base + > > + OFFSET_INTR_MASK); > > + > > + writew(I2C_TRAN_DEFAULT_VALUE, i2c->base + OFFSET_TRANSFER_LEN); > > + writew(I2C_TRANAC_DEFAULT_VALUE, i2c->base + OFFSET_TRANSAC_LEN); > > + > > + writew(I2C_TRANSAC_START | I2C_RS_MUL_CNFG, i2c->base + OFFSET_START); > > + > > + ret = wait_for_completion_timeout(&i2c->msg_complete, > > + i2c->adap.timeout); > > How does the hardware know that this transaction should be a "master code"? > Do you have to tell the hardware what value ('00001XXX') to use as the > master code? > The Master Code must be sent at <= 400 kHz, not the target clock. How > does the hardware know what rate to use? > When sending the master code, arbitration is supposed to occur, such > that only one winning master can proceed with the following high speed > transaction. > Where do you check that you won this arbitration? > If this is not implemented, adding a "TODO" would be helpful. > > > + > > + completion_done(&i2c->msg_complete); > > This completion_done() is only useful if you check the return value. > You should check it too, since we should only check for timeout if the > message hasn't completed. > > > + > > + if (ret == 0) { > > + dev_dbg(i2c->dev, "send master code timeout.\n"); > > + mtk_i2c_init_hw(i2c); > > + return -ETIMEDOUT; > > + } > > + > > + return 0; > > +} > > + > > static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, > > int num, int left_num) > > { > > @@ -539,6 +578,12 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, > > } > > } > > > > + if (i2c->auto_restart && i2c->speed_hz > 400000) { > > Don't we need to send the master code for *every* HS transaction, not > just "auto_restart"? > > "400000" => You already have a macro for this: MAX_FS_MODE_SPEED Please address Daniel's comments and questions. Thanks!
RGVhciBEYW5pZWwsDQoNCjEuIEkgd2lsbCByZW5hbWUgIlRSQU4iICYgIlRSQU5BQyIgJiAiSTJD X1RSQU5fREVGQVVMVF9WQUxVRSIgJiAiSTJDX1RSQU5fREVGQVVMVF9WQUxVRSIuDQoNCjIuIEhv dyBkb2VzIHRoZSBoYXJkd2FyZSBrbm93IHRoYXQgdGhpcyB0cmFuc2FjdGlvbiBzaG91bGQgYmUg YSAibWFzdGVyIGNvZGUiPw0KV2hlbiB3ZSBzZXQgaTJjIHNwZWVkID4gNDAwSyAsIHRoZSBoYXJk d2FyZSB3aWxsIHNlbmQgbWFzdGVyIGNvZGUuIFdlIGhhdmUgYSByZWdpc3RlciB0byBjb25maWd1 cmUgbWFzdGVyIGNvZGXvvIxhbmQgdXN1YWxseSB3ZSB1c2UgdGhlIGRlZmF1bHQgdmFsdWUgIjAw MDAxMDAwIi4NCg0KSG93IGRvZXMgdGhlIGhhcmR3YXJlIGtub3cgd2hhdCByYXRlIHRvIHVzZT8N ClRoZSBpMmMgc3BlZWQgaXMgZGVmaW5lZCBpbiBkdHMsIGFuZCB3ZSB3aWxsIHNldCB0aGUgaTJj IHNwZWVkIGluIGkyYyByZWdpc3Rlciwgc28gSFcgd2lsbCBrbm93IHRoZSByYXRlIHRvIHVzZS4N Cg0KV2hlbiBzZW5kaW5nIHRoZSBtYXN0ZXIgY29kZSwgYXJiaXRyYXRpb24gaXMgc3VwcG9zZWQg dG8gb2NjdXIsIHN1Y2ggdGhhdCBvbmx5IG9uZSB3aW5uaW5nIG1hc3RlciBjYW4gcHJvY2VlZCB3 aXRoIHRoZSBmb2xsb3dpbmcgaGlnaCBzcGVlZCB0cmFuc2FjdGlvbi4NCldoZXJlIGRvIHlvdSBj aGVjayB0aGF0IHlvdSB3b24gdGhpcyBhcmJpdHJhdGlvbj8NCk91ciBpMmMgZHJpdmVyIG5vdyBv bmx5IHN1cHBvcnQgb25lIG1hc3Rlci4NCg0KMy4gSSB3aWxsIGRlbGV0ZSB0aGUgY29tcGxldGlv bl9kb25lKCkgZnVuY3Rpb24uDQoNCjQuIERvbid0IHdlIG5lZWQgdG8gc2VuZCB0aGUgbWFzdGVy IGNvZGUgZm9yICpldmVyeSogSFMgdHJhbnNhY3Rpb24sIG5vdCBqdXN0ICJhdXRvX3Jlc3RhcnQi Pw0KV2hlbiB3ZSBkb24ndCB1c2UgYXV0byByZXN0YXJ0LCB3ZSBhbHNvIG5lZWQgdG8gc2VuZCB0 aGUgbWFzdGVyIGNvZGUsIHRoZSBtYXN0ZXIgY29kZSBpcyBzZW50IGJ5IEhXIGF1dG9tYXRpY2Fs bHkuDQpJIGFtIGltcHJvdmluZyB0aGUgbWFzdGVyIGNvZGUgc2VjdGlvbiB3aGVuIHVzZSBhdXRv IHJlc3RhcnQsIGFuZCB0aGlzIHdpbGwgYmUgcmVsZWFzZWQgaW4gdGhlIG5leHQgcGF0Y2guDQoN CiI0MDAwMDAiID0+IFlvdSBhbHJlYWR5IGhhdmUgYSBtYWNybyBmb3IgdGhpczogTUFYX0ZTX01P REVfU1BFRUQNCg0KWWVzLCBJIHdpbGwgdXNlIE1BWF9GU19NT0RFX1NQRUVELg0KDQpUaGFua3Mh DQoNCi0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQpGcm9tOiBkamt1cnR6QGdvb2dsZS5jb20g W21haWx0bzpkamt1cnR6QGdvb2dsZS5jb21dIE9uIEJlaGFsZiBPZiBEYW5pZWwgS3VydHoNClNl bnQ6IDIwMTXlubQxMeaciDE05pelIDIyOjM5DQpUbzogTGlndW8gWmhhbmcgKOW8oOeri+WbvSkN CkNjOiBXb2xmcmFtIFNhbmc7IHNydl9oZXVwc3RyZWFtOyBNYXR0aGlhcyBCcnVnZ2VyOyBFZGRp ZSBIdWFuZyAo6buD5pm65YKRKTsgWHVkb25nIENoZW4gKOmZiOaXreS4nCk7IFNhc2NoYSBIYXVl cjsgTGludXggSTJDOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOyBsaW51eC1hcm0ta2Vy bmVsQGxpc3RzLmluZnJhZGVhZC5vcmc7IGxpbnV4LW1lZGlhdGVrQGxpc3RzLmluZnJhZGVhZC5v cmcNClN1YmplY3Q6IFJlOiBbUEFUQ0ggdjIgMi8yXSBpMmM6IG1lZGlhdGVrOiBmaXggaTJjIG11 bHRpIHRyYW5zZmVyIGlzc3VlIGluIGhpZ2ggc3BlZWQgbW9kZQ0KDQpPbiBNb24sIE5vdiA5LCAy MDE1IGF0IDE6NDMgUE0sIExpZ3VvIFpoYW5nIDxsaWd1by56aGFuZ0BtZWRpYXRlay5jb20+IHdy b3RlOg0KPiBGb3IgcGxhdGZvcm0gd2l0aCBhdXRvIHJlc3RhcnQgc3VwcG9ydCwgd2hlbiBkb2lu ZyBpMmMgbXVsdGkgdHJhbnNmZXIgDQo+IGluIGhpZ2ggc3BlZWQsIGZvciBleGFtcGxlLCBkb2lu ZyB3cml0ZS10aGVuLXJlYWQgdHJhbnNmZXIsIHRoZSBtYXN0ZXIgDQo+IGNvZGUgd2lsbCBvY2N1 cHkgdGhlIGZpcnN0IHRyYW5zZmVyLCBhbmQgdGhlIHNlY29uZCB0cmFuc2ZlciB3aWxsIGJlIA0K PiB0aGUgcmVhZCB0cmFuc2ZlciwgdGhlIHdyaXRlIHRyYW5zZmVyIHdpbGwgYmUgZGlzY2FyZGVk LiBTbyB3ZSBzaG91bGQgDQo+IGZpcnN0IHNlbmQgdGhlIG1hc3RlciBjb2RlLCBhbmQgdGhlbiBz dGFydCBpMmMgbXVsdGkgdHJhbnNmZXIuDQo+DQo+IFNpZ25lZC1vZmYtYnk6IExpZ3VvIFpoYW5n IDxsaWd1by56aGFuZ0BtZWRpYXRlay5jb20+DQo+IFJldmlld2VkLWJ5OiBFZGRpZSBIdWFuZyA8 ZWRkaWUuaHVhbmdAbWVkaWF0ZWsuY29tPg0KPiAtLS0NCj4gIGRyaXZlcnMvaTJjL2J1c3Nlcy9p MmMtbXQ2NXh4LmMgfCA0NSANCj4gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysNCj4gIDEgZmlsZSBjaGFuZ2VkLCA0NSBpbnNlcnRpb25zKCspDQo+DQo+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL2kyYy9idXNzZXMvaTJjLW10NjV4eC5jIA0KPiBiL2RyaXZlcnMvaTJjL2J1 c3Nlcy9pMmMtbXQ2NXh4LmMgaW5kZXggZGM0YWFjNi4uMjQ5ZGY4NiAxMDA2NDQNCj4gLS0tIGEv ZHJpdmVycy9pMmMvYnVzc2VzL2kyYy1tdDY1eHguYw0KPiArKysgYi9kcml2ZXJzL2kyYy9idXNz ZXMvaTJjLW10NjV4eC5jDQo+IEBAIC01Myw2ICs1Myw4IEBADQo+ICAjZGVmaW5lIEkyQ19GU19U SU1FX0lOSVRfVkFMVUUgICAgICAgICAweDEzMDMNCj4gICNkZWZpbmUgSTJDX1dSUkRfVFJBTkFD X1ZBTFVFICAgICAgICAgIDB4MDAwMg0KPiAgI2RlZmluZSBJMkNfUkRfVFJBTkFDX1ZBTFVFICAg ICAgICAgICAgMHgwMDAxDQo+ICsjZGVmaW5lIEkyQ19UUkFOX0RFRkFVTFRfVkFMVUUgICAgICAg ICAweDAwMDENCj4gKyNkZWZpbmUgSTJDX1RSQU5fREVGQVVMVF9WQUxVRSAgICAgICAweDAwMDEN Cg0KIlRSQU4iIGFuZCAiVFJBTkFDIiBhcmUgbm90IGdvb2QgbmFtZXM7IHRoaXMgc2hvdWxkIGJl ICJUUkFOU0ZFUl9MRU4iDQphbmQgIlRSQU5TQUMiLCBiYXNlZCBvbiB0aGUgbmFtZXMgb2YgdGhl IHJlZ2lzdGVycyB0byB3aGljaCB5b3Ugd3JpdGUgdGhlc2UgY29uc3RhbnRzLg0KDQpGdXJ0aGVy bW9yZSwgdGhlc2UgYXJlIG5vdCAiZGVmYXVsdCIgdmFsdWVzLCB0aGV5IGFyZSB0aGUgdHJhbnNm ZXIgbGVuZ3RoIGFuZCBudW1iZXIgb2YgdHJhbnNhY3Rpb25zIGZvciBzZW5kaW5nIHRoZSAibWFz dGVyIGNvZGUiLCBzbzoNCg0KI2RlZmluZSBJMkNfVFJBTlNGRVJfTEVOX01BU1RFUl9DT0RFICAg ICAgICAgMHgwMDAxDQojZGVmaW5lIEkyQ19UUkFOU0FDX0xFTl9NQVNURVJfQ09ERSAgICAgICAw eDAwMDENCg0KU2ltaWxhcmx5LCBJIHRoaW5rIHRoZSAiVFJBTkFDIiBpbiBJMkNfV1JSRF9UUkFO QUNfVkFMVUUgYW5kIEkyQ19SRF9UUkFOQUNfVkFMVUUgc2hvdWxkIGFsc28gYmUgVFJBTlNBQy4N Cg0KPg0KPiAgI2RlZmluZSBJMkNfRE1BX0NPTl9UWCAgICAgICAgICAgICAgICAgMHgwMDAwDQo+ ICAjZGVmaW5lIEkyQ19ETUFfQ09OX1JYICAgICAgICAgICAgICAgICAweDAwMDENCj4gQEAgLTM2 NSw2ICszNjcsNDMgQEAgc3RhdGljIGludCBtdGtfaTJjX3NldF9zcGVlZChzdHJ1Y3QgbXRrX2ky YyAqaTJjLCB1bnNpZ25lZCBpbnQgcGFyZW50X2NsaywNCj4gICAgICAgICByZXR1cm4gMDsNCj4g IH0NCj4NCj4gK3N0YXRpYyBpbnQgbXRrX2kyY19zZW5kX21hc3Rlcl9jb2RlKHN0cnVjdCBtdGtf aTJjICppMmMpIHsNCj4gKyAgICAgICBpbnQgcmV0ID0gMDsNCj4gKw0KPiArICAgICAgIHJlaW5p dF9jb21wbGV0aW9uKCZpMmMtPm1zZ19jb21wbGV0ZSk7DQo+ICsNCj4gKyAgICAgICB3cml0ZXco STJDX0NPTlRST0xfUlMgfCBJMkNfQ09OVFJPTF9BQ0tFUlJfREVUX0VOIHwNCj4gKyAgICAgICAg ICAgICAgSTJDX0NPTlRST0xfQ0xLX0VYVF9FTiB8IEkyQ19DT05UUk9MX0RNQV9FTiwNCj4gKyAg ICAgICAgICAgICAgaTJjLT5iYXNlICsgT0ZGU0VUX0NPTlRST0wpOw0KPiArDQo+ICsgICAgICAg LyogQ2xlYXIgaW50ZXJydXB0IHN0YXR1cyAqLw0KPiArICAgICAgIHdyaXRldyhJMkNfUlNfVFJB TlNGRVIgfCBJMkNfVFJBTlNBQ19DT01QIHwgSTJDX0hTX05BQ0tFUlIgfCBJMkNfQUNLRVJSLA0K PiArICAgICAgICAgICAgICBpMmMtPmJhc2UgKyBPRkZTRVRfSU5UUl9TVEFUKTsNCj4gKw0KPiAr ICAgICAgIC8qIEVuYWJsZSBpbnRlcnJ1cHQgKi8NCj4gKyAgICAgICB3cml0ZXcoSTJDX1JTX1RS QU5TRkVSIHwgSTJDX1RSQU5TQUNfQ09NUCwgaTJjLT5iYXNlICsNCj4gKyAgICAgICAgICAgICAg T0ZGU0VUX0lOVFJfTUFTSyk7DQo+ICsNCj4gKyAgICAgICB3cml0ZXcoSTJDX1RSQU5fREVGQVVM VF9WQUxVRSwgaTJjLT5iYXNlICsgT0ZGU0VUX1RSQU5TRkVSX0xFTik7DQo+ICsgICAgICAgd3Jp dGV3KEkyQ19UUkFOQUNfREVGQVVMVF9WQUxVRSwgaTJjLT5iYXNlICsgDQo+ICsgT0ZGU0VUX1RS QU5TQUNfTEVOKTsNCj4gKw0KPiArICAgICAgIHdyaXRldyhJMkNfVFJBTlNBQ19TVEFSVCB8IEky Q19SU19NVUxfQ05GRywgaTJjLT5iYXNlICsgDQo+ICsgT0ZGU0VUX1NUQVJUKTsNCj4gKw0KPiAr ICAgICAgIHJldCA9IHdhaXRfZm9yX2NvbXBsZXRpb25fdGltZW91dCgmaTJjLT5tc2dfY29tcGxl dGUsDQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkyYy0+YWRh cC50aW1lb3V0KTsNCg0KSG93IGRvZXMgdGhlIGhhcmR3YXJlIGtub3cgdGhhdCB0aGlzIHRyYW5z YWN0aW9uIHNob3VsZCBiZSBhICJtYXN0ZXIgY29kZSI/DQpEbyB5b3UgaGF2ZSB0byB0ZWxsIHRo ZSBoYXJkd2FyZSB3aGF0IHZhbHVlICgnMDAwMDFYWFgnKSB0byB1c2UgYXMgdGhlIG1hc3RlciBj b2RlPw0KVGhlIE1hc3RlciBDb2RlIG11c3QgYmUgc2VudCBhdCA8PSA0MDAga0h6LCBub3QgdGhl IHRhcmdldCBjbG9jay4gIEhvdyBkb2VzIHRoZSBoYXJkd2FyZSBrbm93IHdoYXQgcmF0ZSB0byB1 c2U/DQpXaGVuIHNlbmRpbmcgdGhlIG1hc3RlciBjb2RlLCBhcmJpdHJhdGlvbiBpcyBzdXBwb3Nl ZCB0byBvY2N1ciwgc3VjaCB0aGF0IG9ubHkgb25lIHdpbm5pbmcgbWFzdGVyIGNhbiBwcm9jZWVk IHdpdGggdGhlIGZvbGxvd2luZyBoaWdoIHNwZWVkIHRyYW5zYWN0aW9uLg0KV2hlcmUgZG8geW91 IGNoZWNrIHRoYXQgeW91IHdvbiB0aGlzIGFyYml0cmF0aW9uPw0KSWYgdGhpcyBpcyBub3QgaW1w bGVtZW50ZWQsIGFkZGluZyBhICJUT0RPIiB3b3VsZCBiZSBoZWxwZnVsLg0KDQo+ICsNCj4gKyAg ICAgICBjb21wbGV0aW9uX2RvbmUoJmkyYy0+bXNnX2NvbXBsZXRlKTsNCg0KVGhpcyBjb21wbGV0 aW9uX2RvbmUoKSBpcyBvbmx5IHVzZWZ1bCBpZiB5b3UgY2hlY2sgdGhlIHJldHVybiB2YWx1ZS4N CllvdSBzaG91bGQgY2hlY2sgaXQgdG9vLCBzaW5jZSB3ZSBzaG91bGQgb25seSBjaGVjayBmb3Ig dGltZW91dCBpZiB0aGUgbWVzc2FnZSBoYXNuJ3QgY29tcGxldGVkLg0KDQo+ICsNCj4gKyAgICAg ICBpZiAocmV0ID09IDApIHsNCj4gKyAgICAgICAgICAgICAgIGRldl9kYmcoaTJjLT5kZXYsICJz ZW5kIG1hc3RlciBjb2RlIHRpbWVvdXQuXG4iKTsNCj4gKyAgICAgICAgICAgICAgIG10a19pMmNf aW5pdF9odyhpMmMpOw0KPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FVElNRURPVVQ7DQo+ICsg ICAgICAgfQ0KPiArDQo+ICsgICAgICAgcmV0dXJuIDA7DQo+ICt9DQo+ICsNCj4gIHN0YXRpYyBp bnQgbXRrX2kyY19kb190cmFuc2ZlcihzdHJ1Y3QgbXRrX2kyYyAqaTJjLCBzdHJ1Y3QgaTJjX21z ZyAqbXNncywNCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW0sIGludCBs ZWZ0X251bSkgIHsgQEAgLTUzOSw2IA0KPiArNTc4LDEyIEBAIHN0YXRpYyBpbnQgbXRrX2kyY190 cmFuc2ZlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXAsDQo+ICAgICAgICAgICAgICAgICB9DQo+ ICAgICAgICAgfQ0KPg0KPiArICAgICAgIGlmIChpMmMtPmF1dG9fcmVzdGFydCAmJiBpMmMtPnNw ZWVkX2h6ID4gNDAwMDAwKSB7DQoNCkRvbid0IHdlIG5lZWQgdG8gc2VuZCB0aGUgbWFzdGVyIGNv ZGUgZm9yICpldmVyeSogSFMgdHJhbnNhY3Rpb24sIG5vdCBqdXN0ICJhdXRvX3Jlc3RhcnQiPw0K DQoiNDAwMDAwIiA9PiBZb3UgYWxyZWFkeSBoYXZlIGEgbWFjcm8gZm9yIHRoaXM6IE1BWF9GU19N T0RFX1NQRUVEDQoNCj4gKyAgICAgICAgICAgICAgIHJldCA9IG10a19pMmNfc2VuZF9tYXN0ZXJf Y29kZShpMmMpOw0KPiArICAgICAgICAgICAgICAgaWYgKHJldCkNCj4gKyAgICAgICAgICAgICAg ICAgICAgICAgcmV0dXJuIHJldDsNCj4gKyAgICAgICB9DQo+ICsNCj4gICAgICAgICB3aGlsZSAo bGVmdF9udW0tLSkgew0KPiAgICAgICAgICAgICAgICAgaWYgKCFtc2dzLT5idWYpIHsNCj4gICAg ICAgICAgICAgICAgICAgICAgICAgZGV2X2RiZyhpMmMtPmRldiwgImRhdGEgYnVmZmVyIGlzIE5V TEwuXG4iKTsNCj4gLS0NCj4gMS44LjEuMS5kaXJ0eQ0KPg0KPiAtLQ0KPiBUbyB1bnN1YnNjcmli ZSBmcm9tIHRoaXMgbGlzdDogc2VuZCB0aGUgbGluZSAidW5zdWJzY3JpYmUgDQo+IGxpbnV4LWtl cm5lbCIgaW4gdGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9tb0B2Z2VyLmtlcm5lbC5v cmcgDQo+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFq b3Jkb21vLWluZm8uaHRtbA0KPiBQbGVhc2UgcmVhZCB0aGUgRkFRIGF0ICBodHRwOi8vd3d3LnR1 eC5vcmcvbGttbC8NCg0KKioqKioqKioqKioqKiBFbWFpbCBDb25maWRlbnRpYWxpdHkgTm90aWNl ICoqKioqKioqKioqKioqKioqKioqDQpUaGUgaW5mb3JtYXRpb24gY29udGFpbmVkIGluIHRoaXMg ZS1tYWlsIG1lc3NhZ2UgKGluY2x1ZGluZyBhbnkgDQphdHRhY2htZW50cykgbWF5IGJlIGNvbmZp ZGVudGlhbCwgcHJvcHJpZXRhcnksIHByaXZpbGVnZWQsIG9yIG90aGVyd2lzZQ0KZXhlbXB0IGZy b20gZGlzY2xvc3VyZSB1bmRlciBhcHBsaWNhYmxlIGxhd3MuIEl0IGlzIGludGVuZGVkIHRvIGJl IA0KY29udmV5ZWQgb25seSB0byB0aGUgZGVzaWduYXRlZCByZWNpcGllbnQocykuIEFueSB1c2Us IGRpc3NlbWluYXRpb24sIA0KZGlzdHJpYnV0aW9uLCBwcmludGluZywgcmV0YWluaW5nIG9yIGNv cHlpbmcgb2YgdGhpcyBlLW1haWwgKGluY2x1ZGluZyBpdHMgDQphdHRhY2htZW50cykgYnkgdW5p bnRlbmRlZCByZWNpcGllbnQocykgaXMgc3RyaWN0bHkgcHJvaGliaXRlZCBhbmQgbWF5IA0KYmUg dW5sYXdmdWwuIElmIHlvdSBhcmUgbm90IGFuIGludGVuZGVkIHJlY2lwaWVudCBvZiB0aGlzIGUt bWFpbCwgb3IgYmVsaWV2ZSANCnRoYXQgeW91IGhhdmUgcmVjZWl2ZWQgdGhpcyBlLW1haWwgaW4g ZXJyb3IsIHBsZWFzZSBub3RpZnkgdGhlIHNlbmRlciANCmltbWVkaWF0ZWx5IChieSByZXBseWlu ZyB0byB0aGlzIGUtbWFpbCksIGRlbGV0ZSBhbnkgYW5kIGFsbCBjb3BpZXMgb2YgDQp0aGlzIGUt bWFpbCAoaW5jbHVkaW5nIGFueSBhdHRhY2htZW50cykgZnJvbSB5b3VyIHN5c3RlbSwgYW5kIGRv IG5vdA0KZGlzY2xvc2UgdGhlIGNvbnRlbnQgb2YgdGhpcyBlLW1haWwgdG8gYW55IG90aGVyIHBl cnNvbi4gVGhhbmsgeW91IQ0K -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, 2015-11-14 at 22:38 +0800, Daniel Kurtz wrote: > On Mon, Nov 9, 2015 at 1:43 PM, Liguo Zhang <liguo.zhang@mediatek.com> wrote: > > For platform with auto restart support, when doing i2c multi transfer > > in high speed, for example, doing write-then-read transfer, the master > > code will occupy the first transfer, and the second transfer will be > > the read transfer, the write transfer will be discarded. So we should > > first send the master code, and then start i2c multi transfer. > > > > Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com> > > Reviewed-by: Eddie Huang <eddie.huang@mediatek.com> > > --- > > drivers/i2c/busses/i2c-mt65xx.c | 45 +++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 45 insertions(+) > > > > diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c > > index dc4aac6..249df86 100644 > > --- a/drivers/i2c/busses/i2c-mt65xx.c > > +++ b/drivers/i2c/busses/i2c-mt65xx.c > > @@ -53,6 +53,8 @@ > > #define I2C_FS_TIME_INIT_VALUE 0x1303 > > #define I2C_WRRD_TRANAC_VALUE 0x0002 > > #define I2C_RD_TRANAC_VALUE 0x0001 > > +#define I2C_TRAN_DEFAULT_VALUE 0x0001 > > +#define I2C_TRANAC_DEFAULT_VALUE 0x0001 > > "TRAN" and "TRANAC" are not good names; this should be "TRANSFER_LEN" > and "TRANSAC", based on the names of the registers to which you write > these constants. > > Furthermore, these are not "default" values, they are the transfer > length and number of transactions for sending the "master code", so: > > #define I2C_TRANSFER_LEN_MASTER_CODE 0x0001 > #define I2C_TRANSAC_LEN_MASTER_CODE 0x0001 > > Similarly, I think the "TRANAC" in I2C_WRRD_TRANAC_VALUE and > I2C_RD_TRANAC_VALUE should also be TRANSAC. > Yes, I will follow your advice. > > > > #define I2C_DMA_CON_TX 0x0000 > > #define I2C_DMA_CON_RX 0x0001 > > @@ -365,6 +367,43 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk, > > return 0; > > } > > > > +static int mtk_i2c_send_master_code(struct mtk_i2c *i2c) > > +{ > > + int ret = 0; > > + > > + reinit_completion(&i2c->msg_complete); > > + > > + writew(I2C_CONTROL_RS | I2C_CONTROL_ACKERR_DET_EN | > > + I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN, > > + i2c->base + OFFSET_CONTROL); > > + > > + /* Clear interrupt status */ > > + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP | I2C_HS_NACKERR | I2C_ACKERR, > > + i2c->base + OFFSET_INTR_STAT); > > + > > + /* Enable interrupt */ > > + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP, i2c->base + > > + OFFSET_INTR_MASK); > > + > > + writew(I2C_TRAN_DEFAULT_VALUE, i2c->base + OFFSET_TRANSFER_LEN); > > + writew(I2C_TRANAC_DEFAULT_VALUE, i2c->base + OFFSET_TRANSAC_LEN); > > + > > + writew(I2C_TRANSAC_START | I2C_RS_MUL_CNFG, i2c->base + OFFSET_START); > > + > > + ret = wait_for_completion_timeout(&i2c->msg_complete, > > + i2c->adap.timeout); > > How does the hardware know that this transaction should be a "master code"? > Do you have to tell the hardware what value ('00001XXX') to use as the > master code? When we set i2c speed > 400K , the hardware will send master code. We have a register to configure master codeļ¼and usually we use the default value "00001000". > The Master Code must be sent at <= 400 kHz, not the target clock. How > does the hardware know what rate to use? The i2c speed is defined in dts, and we will set the i2c speed in i2c register, so HW will know the rate to use. > When sending the master code, arbitration is supposed to occur, such > that only one winning master can proceed with the following high speed > transaction. > Where do you check that you won this arbitration? > If this is not implemented, adding a "TODO" would be helpful. > Our i2c driver now only support one master. > > + > > + completion_done(&i2c->msg_complete); > > This completion_done() is only useful if you check the return value. > You should check it too, since we should only check for timeout if the > message hasn't completed. > I will delete the completion_done() function. > > + > > + if (ret == 0) { > > + dev_dbg(i2c->dev, "send master code timeout.\n"); > > + mtk_i2c_init_hw(i2c); > > + return -ETIMEDOUT; > > + } > > + > > + return 0; > > +} > > + > > static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, > > int num, int left_num) > > { > > @@ -539,6 +578,12 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, > > } > > } > > > > + if (i2c->auto_restart && i2c->speed_hz > 400000) { > > Don't we need to send the master code for *every* HS transaction, not > just "auto_restart"? > When we don't use auto restart, we also need to send the master code, the master code is sent by HW automatically. I am improving the master code section when use auto restart, and this will be released in the next patch. > "400000" => You already have a macro for this: MAX_FS_MODE_SPEED > Yes, I will use MAX_FS_MODE_SPEED. > > + ret = mtk_i2c_send_master_code(i2c); > > + if (ret) > > + return ret; > > + } > > + > > while (left_num--) { > > if (!msgs->buf) { > > dev_dbg(i2c->dev, "data buffer is NULL.\n"); > > -- > > 1.8.1.1.dirty > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index dc4aac6..249df86 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -53,6 +53,8 @@ #define I2C_FS_TIME_INIT_VALUE 0x1303 #define I2C_WRRD_TRANAC_VALUE 0x0002 #define I2C_RD_TRANAC_VALUE 0x0001 +#define I2C_TRAN_DEFAULT_VALUE 0x0001 +#define I2C_TRANAC_DEFAULT_VALUE 0x0001 #define I2C_DMA_CON_TX 0x0000 #define I2C_DMA_CON_RX 0x0001 @@ -365,6 +367,43 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk, return 0; } +static int mtk_i2c_send_master_code(struct mtk_i2c *i2c) +{ + int ret = 0; + + reinit_completion(&i2c->msg_complete); + + writew(I2C_CONTROL_RS | I2C_CONTROL_ACKERR_DET_EN | + I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN, + i2c->base + OFFSET_CONTROL); + + /* Clear interrupt status */ + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP | I2C_HS_NACKERR | I2C_ACKERR, + i2c->base + OFFSET_INTR_STAT); + + /* Enable interrupt */ + writew(I2C_RS_TRANSFER | I2C_TRANSAC_COMP, i2c->base + + OFFSET_INTR_MASK); + + writew(I2C_TRAN_DEFAULT_VALUE, i2c->base + OFFSET_TRANSFER_LEN); + writew(I2C_TRANAC_DEFAULT_VALUE, i2c->base + OFFSET_TRANSAC_LEN); + + writew(I2C_TRANSAC_START | I2C_RS_MUL_CNFG, i2c->base + OFFSET_START); + + ret = wait_for_completion_timeout(&i2c->msg_complete, + i2c->adap.timeout); + + completion_done(&i2c->msg_complete); + + if (ret == 0) { + dev_dbg(i2c->dev, "send master code timeout.\n"); + mtk_i2c_init_hw(i2c); + return -ETIMEDOUT; + } + + return 0; +} + static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, int num, int left_num) { @@ -539,6 +578,12 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, } } + if (i2c->auto_restart && i2c->speed_hz > 400000) { + ret = mtk_i2c_send_master_code(i2c); + if (ret) + return ret; + } + while (left_num--) { if (!msgs->buf) { dev_dbg(i2c->dev, "data buffer is NULL.\n");