diff mbox

[v3] aspeed/smc: handle dummy bytes when doing fast reads in command mode

Message ID 1484751701-2646-1-git-send-email-clg@kaod.org
State New
Headers show

Commit Message

Cédric Le Goater Jan. 18, 2017, 3:01 p.m. UTC
When doing fast read, a certain amount of dummy bytes should be sent
before the read. This number is configurable in the controler CE0
Control Register and needs to be modeled using fake transfers to the
flash module.

This only supports command mode. User mode requires more work and a
possible extension of the m25p80 device model.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes since v2:

 - handled dummies under read routine and removed the test on the spi
   command READ_FAST (0xb)

 hw/ssi/aspeed_smc.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

mar.krzeminski Jan. 18, 2017, 6:23 p.m. UTC | #1
W dniu 18.01.2017 o 16:01, Cédric Le Goater pisze:
> When doing fast read, a certain amount of dummy bytes should be sent
> before the read. This number is configurable in the controler CE0
> Control Register and needs to be modeled using fake transfers to the
> flash module.
>
> This only supports command mode. User mode requires more work and a
> possible extension of the m25p80 device model.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>
>   Changes since v2:
>
>   - handled dummies under read routine and removed the test on the spi
>     command READ_FAST (0xb)
>
>   hw/ssi/aspeed_smc.c | 21 +++++++++++++++++++++
>   1 file changed, 21 insertions(+)
>
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index a0a816407fc1..fc3cccec0566 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -69,7 +69,9 @@
>   #define R_CTRL0           (0x10 / 4)
>   #define   CTRL_CMD_SHIFT           16
>   #define   CTRL_CMD_MASK            0xff
> +#define   CTRL_DUMMY_HIGH_SHIFT    14
>   #define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
> +#define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
>   #define   CTRL_CE_STOP_ACTIVE      (1 << 2)
>   #define   CTRL_CMD_MODE_MASK       0x3
>   #define     CTRL_READMODE          0x0
> @@ -490,6 +492,16 @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
>       return addr;
>   }
>   
> +static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
> +{
> +    const AspeedSMCState *s = fl->controller;
> +    uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
> +    uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
> +    uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
> +
> +    return ((dummy_high << 2) | dummy_low) * 8;
> +}
> +
>   static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
>   {
>       const AspeedSMCState *s = fl->controller;
> @@ -526,6 +538,15 @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
>           aspeed_smc_flash_select(fl);
>           aspeed_smc_flash_send_addr(fl, addr);
>   
> +        /*
> +         * Use fake transfers to model dummy bytes. The value should
> +         * be configured to some non-zero value in fast read mode and
> +         * zero in read mode.
> +         */
> +        for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
> +            ssi_transfer(fl->controller->spi, 0xFF);
> +        }
> +
>           for (i = 0; i < size; i++) {
>               ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
>           }
If it does not break CTRL_WRITEMODE then:
Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>
Cédric Le Goater Jan. 23, 2017, 10:05 a.m. UTC | #2
On 01/18/2017 07:23 PM, mar.krzeminski wrote:
> W dniu 18.01.2017 o 16:01, Cédric Le Goater pisze:
>> When doing fast read, a certain amount of dummy bytes should be sent
>> before the read. This number is configurable in the controler CE0
>> Control Register and needs to be modeled using fake transfers to the
>> flash module.
>>
>> This only supports command mode. User mode requires more work and a
>> possible extension of the m25p80 device model.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>
>>   Changes since v2:
>>
>>   - handled dummies under read routine and removed the test on the spi
>>     command READ_FAST (0xb)
>>
>>   hw/ssi/aspeed_smc.c | 21 +++++++++++++++++++++
>>   1 file changed, 21 insertions(+)
>>
>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
>> index a0a816407fc1..fc3cccec0566 100644
>> --- a/hw/ssi/aspeed_smc.c
>> +++ b/hw/ssi/aspeed_smc.c
>> @@ -69,7 +69,9 @@
>>   #define R_CTRL0           (0x10 / 4)
>>   #define   CTRL_CMD_SHIFT           16
>>   #define   CTRL_CMD_MASK            0xff
>> +#define   CTRL_DUMMY_HIGH_SHIFT    14
>>   #define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
>> +#define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
>>   #define   CTRL_CE_STOP_ACTIVE      (1 << 2)
>>   #define   CTRL_CMD_MODE_MASK       0x3
>>   #define     CTRL_READMODE          0x0
>> @@ -490,6 +492,16 @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
>>       return addr;
>>   }
>>   +static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
>> +{
>> +    const AspeedSMCState *s = fl->controller;
>> +    uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
>> +    uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
>> +    uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
>> +
>> +    return ((dummy_high << 2) | dummy_low) * 8;
>> +}
>> +
>>   static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
>>   {
>>       const AspeedSMCState *s = fl->controller;
>> @@ -526,6 +538,15 @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
>>           aspeed_smc_flash_select(fl);
>>           aspeed_smc_flash_send_addr(fl, addr);
>>   +        /*
>> +         * Use fake transfers to model dummy bytes. The value should
>> +         * be configured to some non-zero value in fast read mode and
>> +         * zero in read mode.
>> +         */
>> +        for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
>> +            ssi_transfer(fl->controller->spi, 0xFF);
>> +        }
>> +
>>           for (i = 0; i < size; i++) {
>>               ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
>>           }
> If it does not break CTRL_WRITEMODE then:
> Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>

yes. now the dummy transfers are under the CTRL_FREADMODE case, 
which is the same as CTRL_READMODE but in this case, the number 
of dummies should zero.

Thanks,

C.
Peter Maydell Jan. 24, 2017, 11:45 a.m. UTC | #3
On 18 January 2017 at 15:01, Cédric Le Goater <clg@kaod.org> wrote:
> When doing fast read, a certain amount of dummy bytes should be sent
> before the read. This number is configurable in the controler CE0
> Control Register and needs to be modeled using fake transfers to the
> flash module.
>
> This only supports command mode. User mode requires more work and a
> possible extension of the m25p80 device model.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>



Applied to target-arm.next, thanks.

-- PMM
diff mbox

Patch

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index a0a816407fc1..fc3cccec0566 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -69,7 +69,9 @@ 
 #define R_CTRL0           (0x10 / 4)
 #define   CTRL_CMD_SHIFT           16
 #define   CTRL_CMD_MASK            0xff
+#define   CTRL_DUMMY_HIGH_SHIFT    14
 #define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
+#define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
 #define   CTRL_CE_STOP_ACTIVE      (1 << 2)
 #define   CTRL_CMD_MODE_MASK       0x3
 #define     CTRL_READMODE          0x0
@@ -490,6 +492,16 @@  static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
     return addr;
 }
 
+static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
+{
+    const AspeedSMCState *s = fl->controller;
+    uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
+    uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
+    uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
+
+    return ((dummy_high << 2) | dummy_low) * 8;
+}
+
 static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
 {
     const AspeedSMCState *s = fl->controller;
@@ -526,6 +538,15 @@  static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
         aspeed_smc_flash_select(fl);
         aspeed_smc_flash_send_addr(fl, addr);
 
+        /*
+         * Use fake transfers to model dummy bytes. The value should
+         * be configured to some non-zero value in fast read mode and
+         * zero in read mode.
+         */
+        for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
+            ssi_transfer(fl->controller->spi, 0xFF);
+        }
+
         for (i = 0; i < size; i++) {
             ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
         }