diff mbox series

[1/3] aspeed/i2c: interrupts should be cleared by software only

Message ID 20180914063506.20815-2-clg@kaod.org
State New
Headers show
Series aspeed/i2c: fix receive done interrupt model | expand

Commit Message

Cédric Le Goater Sept. 14, 2018, 6:35 a.m. UTC
and the bus interrupt should be lowered when all interrupts have been
cleared. Also, the model does not implement correctly the RX_DONE bit
behavior which should be cleared to allow more data to be received.
Yet to be fixed.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/i2c/aspeed_i2c.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

Comments

Peter Maydell Sept. 25, 2018, 9:02 a.m. UTC | #1
On 14 September 2018 at 07:35, Cédric Le Goater <clg@kaod.org> wrote:
> and the bus interrupt should be lowered when all interrupts have been
> cleared. Also, the model does not implement correctly the RX_DONE bit
> behavior which should be cleared to allow more data to be received.
> Yet to be fixed.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/i2c/aspeed_i2c.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
> index c762c7366ad9..de6b08378675 100644
> --- a/hw/i2c/aspeed_i2c.c
> +++ b/hw/i2c/aspeed_i2c.c
> @@ -52,6 +52,13 @@
>  #define I2CD_AC_TIMING_REG2     0x08       /* Clock and AC Timing Control #1 */
>  #define I2CD_INTR_CTRL_REG      0x0c       /* I2CD Interrupt Control */
>  #define I2CD_INTR_STS_REG       0x10       /* I2CD Interrupt Status */
> +
> +#define   I2CD_INTR_SLAVE_ADDR_MATCH       (0x1 << 31) /* 0: addr1 1: addr2 */
> +#define   I2CD_INTR_SLAVE_ADDR_RX_PENDING  (0x1 << 30)
> +/* bits[19-16] Reserved */
> +
> +/* All bits below are cleared by writing 1 */
> +#define   I2CD_INTR_SLAVE_INACTIVE_TIMEOUT (0x1 << 15)
>  #define   I2CD_INTR_SDA_DL_TIMEOUT         (0x1 << 14)
>  #define   I2CD_INTR_BUS_RECOVER_DONE       (0x1 << 13)
>  #define   I2CD_INTR_SMBUS_ALERT            (0x1 << 12) /* Bus [0-3] only */
> @@ -59,11 +66,16 @@
>  #define   I2CD_INTR_SMBUS_DEV_ALERT_ADDR   (0x1 << 10) /* Removed */
>  #define   I2CD_INTR_SMBUS_DEF_ADDR         (0x1 << 9)  /* Removed */
>  #define   I2CD_INTR_GCALL_ADDR             (0x1 << 8)  /* Removed */
> -#define   I2CD_INTR_SLAVE_MATCH            (0x1 << 7)  /* use RX_DONE */
> +#define   I2CD_INTR_SLAVE_ADDR_RX_MATCH    (0x1 << 7)  /* use RX_DONE */
>  #define   I2CD_INTR_SCL_TIMEOUT            (0x1 << 6)
>  #define   I2CD_INTR_ABNORMAL               (0x1 << 5)
>  #define   I2CD_INTR_NORMAL_STOP            (0x1 << 4)
>  #define   I2CD_INTR_ARBIT_LOSS             (0x1 << 3)
> +
> +/*
> + * TODO: handle correctly I2CD_INTR_RX_DONE which needs to be cleared
> + * to allow next data to be received.
> + */
>  #define   I2CD_INTR_RX_DONE                (0x1 << 2)

Is this TODO something different from the behaviour involving
this RX_DONE bit which is fixed in patch 3 in this set ?

thanks
-- PMM
Cédric Le Goater Sept. 25, 2018, 9:12 a.m. UTC | #2
On 09/25/2018 11:02 AM, Peter Maydell wrote:
> On 14 September 2018 at 07:35, Cédric Le Goater <clg@kaod.org> wrote:
>> and the bus interrupt should be lowered when all interrupts have been
>> cleared. Also, the model does not implement correctly the RX_DONE bit
>> behavior which should be cleared to allow more data to be received.
>> Yet to be fixed.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/i2c/aspeed_i2c.c | 21 +++++++++++++++++----
>>  1 file changed, 17 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
>> index c762c7366ad9..de6b08378675 100644
>> --- a/hw/i2c/aspeed_i2c.c
>> +++ b/hw/i2c/aspeed_i2c.c
>> @@ -52,6 +52,13 @@
>>  #define I2CD_AC_TIMING_REG2     0x08       /* Clock and AC Timing Control #1 */
>>  #define I2CD_INTR_CTRL_REG      0x0c       /* I2CD Interrupt Control */
>>  #define I2CD_INTR_STS_REG       0x10       /* I2CD Interrupt Status */
>> +
>> +#define   I2CD_INTR_SLAVE_ADDR_MATCH       (0x1 << 31) /* 0: addr1 1: addr2 */
>> +#define   I2CD_INTR_SLAVE_ADDR_RX_PENDING  (0x1 << 30)
>> +/* bits[19-16] Reserved */
>> +
>> +/* All bits below are cleared by writing 1 */
>> +#define   I2CD_INTR_SLAVE_INACTIVE_TIMEOUT (0x1 << 15)
>>  #define   I2CD_INTR_SDA_DL_TIMEOUT         (0x1 << 14)
>>  #define   I2CD_INTR_BUS_RECOVER_DONE       (0x1 << 13)
>>  #define   I2CD_INTR_SMBUS_ALERT            (0x1 << 12) /* Bus [0-3] only */
>> @@ -59,11 +66,16 @@
>>  #define   I2CD_INTR_SMBUS_DEV_ALERT_ADDR   (0x1 << 10) /* Removed */
>>  #define   I2CD_INTR_SMBUS_DEF_ADDR         (0x1 << 9)  /* Removed */
>>  #define   I2CD_INTR_GCALL_ADDR             (0x1 << 8)  /* Removed */
>> -#define   I2CD_INTR_SLAVE_MATCH            (0x1 << 7)  /* use RX_DONE */
>> +#define   I2CD_INTR_SLAVE_ADDR_RX_MATCH    (0x1 << 7)  /* use RX_DONE */
>>  #define   I2CD_INTR_SCL_TIMEOUT            (0x1 << 6)
>>  #define   I2CD_INTR_ABNORMAL               (0x1 << 5)
>>  #define   I2CD_INTR_NORMAL_STOP            (0x1 << 4)
>>  #define   I2CD_INTR_ARBIT_LOSS             (0x1 << 3)
>> +
>> +/*
>> + * TODO: handle correctly I2CD_INTR_RX_DONE which needs to be cleared
>> + * to allow next data to be received.
>> + */
>>  #define   I2CD_INTR_RX_DONE                (0x1 << 2)
> 
> Is this TODO something different from the behaviour involving
> this RX_DONE bit which is fixed in patch 3 in this set ?

no. It's the same but the TODO was not removed. I intended to do
so after a possible merge.

Thanks,

C.
Peter Maydell Sept. 25, 2018, 10:15 a.m. UTC | #3
On 25 September 2018 at 10:12, Cédric Le Goater <clg@kaod.org> wrote:
> On 09/25/2018 11:02 AM, Peter Maydell wrote:
>> On 14 September 2018 at 07:35, Cédric Le Goater <clg@kaod.org> wrote:
>>> and the bus interrupt should be lowered when all interrupts have been
>>> cleared. Also, the model does not implement correctly the RX_DONE bit
>>> behavior which should be cleared to allow more data to be received.
>>> Yet to be fixed.
>>>
>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>> ---
>>>  hw/i2c/aspeed_i2c.c | 21 +++++++++++++++++----
>>>  1 file changed, 17 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
>>> index c762c7366ad9..de6b08378675 100644
>>> --- a/hw/i2c/aspeed_i2c.c
>>> +++ b/hw/i2c/aspeed_i2c.c
>>> @@ -52,6 +52,13 @@
>>>  #define I2CD_AC_TIMING_REG2     0x08       /* Clock and AC Timing Control #1 */
>>>  #define I2CD_INTR_CTRL_REG      0x0c       /* I2CD Interrupt Control */
>>>  #define I2CD_INTR_STS_REG       0x10       /* I2CD Interrupt Status */
>>> +
>>> +#define   I2CD_INTR_SLAVE_ADDR_MATCH       (0x1 << 31) /* 0: addr1 1: addr2 */
>>> +#define   I2CD_INTR_SLAVE_ADDR_RX_PENDING  (0x1 << 30)
>>> +/* bits[19-16] Reserved */
>>> +
>>> +/* All bits below are cleared by writing 1 */
>>> +#define   I2CD_INTR_SLAVE_INACTIVE_TIMEOUT (0x1 << 15)
>>>  #define   I2CD_INTR_SDA_DL_TIMEOUT         (0x1 << 14)
>>>  #define   I2CD_INTR_BUS_RECOVER_DONE       (0x1 << 13)
>>>  #define   I2CD_INTR_SMBUS_ALERT            (0x1 << 12) /* Bus [0-3] only */
>>> @@ -59,11 +66,16 @@
>>>  #define   I2CD_INTR_SMBUS_DEV_ALERT_ADDR   (0x1 << 10) /* Removed */
>>>  #define   I2CD_INTR_SMBUS_DEF_ADDR         (0x1 << 9)  /* Removed */
>>>  #define   I2CD_INTR_GCALL_ADDR             (0x1 << 8)  /* Removed */
>>> -#define   I2CD_INTR_SLAVE_MATCH            (0x1 << 7)  /* use RX_DONE */
>>> +#define   I2CD_INTR_SLAVE_ADDR_RX_MATCH    (0x1 << 7)  /* use RX_DONE */
>>>  #define   I2CD_INTR_SCL_TIMEOUT            (0x1 << 6)
>>>  #define   I2CD_INTR_ABNORMAL               (0x1 << 5)
>>>  #define   I2CD_INTR_NORMAL_STOP            (0x1 << 4)
>>>  #define   I2CD_INTR_ARBIT_LOSS             (0x1 << 3)
>>> +
>>> +/*
>>> + * TODO: handle correctly I2CD_INTR_RX_DONE which needs to be cleared
>>> + * to allow next data to be received.
>>> + */
>>>  #define   I2CD_INTR_RX_DONE                (0x1 << 2)
>>
>> Is this TODO something different from the behaviour involving
>> this RX_DONE bit which is fixed in patch 3 in this set ?
>
> no. It's the same but the TODO was not removed. I intended to do
> so after a possible merge.

OK. I'll fix up the commit message and drop the TODO message from
this patch when I put the series into target-arm.next, if that's ok.

thanks
-- PMM
Cédric Le Goater Sept. 25, 2018, 10:44 a.m. UTC | #4
On 09/25/2018 12:15 PM, Peter Maydell wrote:
> On 25 September 2018 at 10:12, Cédric Le Goater <clg@kaod.org> wrote:
>> On 09/25/2018 11:02 AM, Peter Maydell wrote:
>>> On 14 September 2018 at 07:35, Cédric Le Goater <clg@kaod.org> wrote:
>>>> and the bus interrupt should be lowered when all interrupts have been
>>>> cleared. Also, the model does not implement correctly the RX_DONE bit
>>>> behavior which should be cleared to allow more data to be received.
>>>> Yet to be fixed.
>>>>
>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>> ---
>>>>  hw/i2c/aspeed_i2c.c | 21 +++++++++++++++++----
>>>>  1 file changed, 17 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
>>>> index c762c7366ad9..de6b08378675 100644
>>>> --- a/hw/i2c/aspeed_i2c.c
>>>> +++ b/hw/i2c/aspeed_i2c.c
>>>> @@ -52,6 +52,13 @@
>>>>  #define I2CD_AC_TIMING_REG2     0x08       /* Clock and AC Timing Control #1 */
>>>>  #define I2CD_INTR_CTRL_REG      0x0c       /* I2CD Interrupt Control */
>>>>  #define I2CD_INTR_STS_REG       0x10       /* I2CD Interrupt Status */
>>>> +
>>>> +#define   I2CD_INTR_SLAVE_ADDR_MATCH       (0x1 << 31) /* 0: addr1 1: addr2 */
>>>> +#define   I2CD_INTR_SLAVE_ADDR_RX_PENDING  (0x1 << 30)
>>>> +/* bits[19-16] Reserved */
>>>> +
>>>> +/* All bits below are cleared by writing 1 */
>>>> +#define   I2CD_INTR_SLAVE_INACTIVE_TIMEOUT (0x1 << 15)
>>>>  #define   I2CD_INTR_SDA_DL_TIMEOUT         (0x1 << 14)
>>>>  #define   I2CD_INTR_BUS_RECOVER_DONE       (0x1 << 13)
>>>>  #define   I2CD_INTR_SMBUS_ALERT            (0x1 << 12) /* Bus [0-3] only */
>>>> @@ -59,11 +66,16 @@
>>>>  #define   I2CD_INTR_SMBUS_DEV_ALERT_ADDR   (0x1 << 10) /* Removed */
>>>>  #define   I2CD_INTR_SMBUS_DEF_ADDR         (0x1 << 9)  /* Removed */
>>>>  #define   I2CD_INTR_GCALL_ADDR             (0x1 << 8)  /* Removed */
>>>> -#define   I2CD_INTR_SLAVE_MATCH            (0x1 << 7)  /* use RX_DONE */
>>>> +#define   I2CD_INTR_SLAVE_ADDR_RX_MATCH    (0x1 << 7)  /* use RX_DONE */
>>>>  #define   I2CD_INTR_SCL_TIMEOUT            (0x1 << 6)
>>>>  #define   I2CD_INTR_ABNORMAL               (0x1 << 5)
>>>>  #define   I2CD_INTR_NORMAL_STOP            (0x1 << 4)
>>>>  #define   I2CD_INTR_ARBIT_LOSS             (0x1 << 3)
>>>> +
>>>> +/*
>>>> + * TODO: handle correctly I2CD_INTR_RX_DONE which needs to be cleared
>>>> + * to allow next data to be received.
>>>> + */
>>>>  #define   I2CD_INTR_RX_DONE                (0x1 << 2)
>>>
>>> Is this TODO something different from the behaviour involving
>>> this RX_DONE bit which is fixed in patch 3 in this set ?
>>
>> no. It's the same but the TODO was not removed. I intended to do
>> so after a possible merge.
> 
> OK. I'll fix up the commit message and drop the TODO message from
> this patch when I put the series into target-arm.next, if that's ok.

Sure. 

Thanks,

C.
diff mbox series

Patch

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index c762c7366ad9..de6b08378675 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -52,6 +52,13 @@ 
 #define I2CD_AC_TIMING_REG2     0x08       /* Clock and AC Timing Control #1 */
 #define I2CD_INTR_CTRL_REG      0x0c       /* I2CD Interrupt Control */
 #define I2CD_INTR_STS_REG       0x10       /* I2CD Interrupt Status */
+
+#define   I2CD_INTR_SLAVE_ADDR_MATCH       (0x1 << 31) /* 0: addr1 1: addr2 */
+#define   I2CD_INTR_SLAVE_ADDR_RX_PENDING  (0x1 << 30)
+/* bits[19-16] Reserved */
+
+/* All bits below are cleared by writing 1 */
+#define   I2CD_INTR_SLAVE_INACTIVE_TIMEOUT (0x1 << 15)
 #define   I2CD_INTR_SDA_DL_TIMEOUT         (0x1 << 14)
 #define   I2CD_INTR_BUS_RECOVER_DONE       (0x1 << 13)
 #define   I2CD_INTR_SMBUS_ALERT            (0x1 << 12) /* Bus [0-3] only */
@@ -59,11 +66,16 @@ 
 #define   I2CD_INTR_SMBUS_DEV_ALERT_ADDR   (0x1 << 10) /* Removed */
 #define   I2CD_INTR_SMBUS_DEF_ADDR         (0x1 << 9)  /* Removed */
 #define   I2CD_INTR_GCALL_ADDR             (0x1 << 8)  /* Removed */
-#define   I2CD_INTR_SLAVE_MATCH            (0x1 << 7)  /* use RX_DONE */
+#define   I2CD_INTR_SLAVE_ADDR_RX_MATCH    (0x1 << 7)  /* use RX_DONE */
 #define   I2CD_INTR_SCL_TIMEOUT            (0x1 << 6)
 #define   I2CD_INTR_ABNORMAL               (0x1 << 5)
 #define   I2CD_INTR_NORMAL_STOP            (0x1 << 4)
 #define   I2CD_INTR_ARBIT_LOSS             (0x1 << 3)
+
+/*
+ * TODO: handle correctly I2CD_INTR_RX_DONE which needs to be cleared
+ * to allow next data to be received.
+ */
 #define   I2CD_INTR_RX_DONE                (0x1 << 2)
 #define   I2CD_INTR_TX_NAK                 (0x1 << 1)
 #define   I2CD_INTR_TX_ACK                 (0x1 << 0)
@@ -188,7 +200,6 @@  static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
 {
     bus->cmd &= ~0xFFFF;
     bus->cmd |= value & 0xFFFF;
-    bus->intr_status = 0;
 
     if (bus->cmd & I2CD_M_START_CMD) {
         uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
@@ -284,8 +295,10 @@  static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
         break;
     case I2CD_INTR_STS_REG:
         bus->intr_status &= ~(value & 0x7FFF);
-        bus->controller->intr_status &= ~(1 << bus->id);
-        qemu_irq_lower(bus->controller->irq);
+        if (!bus->intr_status) {
+            bus->controller->intr_status &= ~(1 << bus->id);
+            qemu_irq_lower(bus->controller->irq);
+        }
         break;
     case I2CD_DEV_ADDR_REG:
         qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",