qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] hw/sd/bcm2835_sdhost: Fix PIO mode writes


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-devel] [PATCH] hw/sd/bcm2835_sdhost: Fix PIO mode writes
Date: Mon, 16 Jul 2018 22:20:37 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

Cc'ing ANTField folks who might have the specs.

On 07/16/2018 07:23 PM, Guenter Roeck wrote:
> Writes in PIO mode have two requirements:
> 
> - A data interrupt must be generated after a write command has been
>   issued to indicate that the chip is ready to receive data.
> - A block interrupt must be generated after each block to indicate
>   that the chip is ready to receive the next data block.
> 
> Rearrange the code to make this happen. Tested on raspi3 (in PIO mode)
> and raspi2 (in DMA mode).

Note to reviewers, this seems a follow-up of:
http://lists.nongnu.org/archive/html/qemu-devel/2018-07/msg03397.html
(This patch makes more sens after reading this previous thread).

> 
> Signed-off-by: Guenter Roeck <address@hidden>
> ---
>  hw/sd/bcm2835_sdhost.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
> index 4df4de7..1b760b2 100644
> --- a/hw/sd/bcm2835_sdhost.c
> +++ b/hw/sd/bcm2835_sdhost.c
> @@ -179,9 +179,11 @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState 
> *s)
>      uint32_t value = 0;
>      int n;
>      int is_read;
> +    int is_write;
>  
>      is_read = (s->cmd & SDCMD_READ_CMD) != 0;
> -    if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus))) {
> +    is_write = (s->cmd & SDCMD_WRITE_CMD) != 0;
> +    if (s->datacnt != 0 && (is_write || sdbus_data_ready(&s->sdbus))) {
>          if (is_read) {
>              n = 0;
>              while (s->datacnt && s->fifo_len < BCM2835_SDHOST_FIFO_LEN) {
> @@ -201,8 +203,11 @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState 
> *s)
>              if (n != 0) {
>                  bcm2835_sdhost_fifo_push(s, value);
>                  s->status |= SDHSTS_DATA_FLAG;
> +                if (s->config & SDHCFG_DATA_IRPT_EN) {
> +                    s->status |= SDHSTS_SDIO_IRPT;
> +                }
>              }
> -        } else { /* write */
> +        } else if (is_write) { /* write */
>              n = 0;
>              while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
>                  if (n == 0) {
> @@ -223,11 +228,18 @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState 
> *s)
>              s->edm &= ~SDEDM_FSM_MASK;
>              s->edm |= SDEDM_FSM_DATAMODE;
>              trace_bcm2835_sdhost_edm_change("datacnt 0", s->edm);
> -
> -            if ((s->cmd & SDCMD_WRITE_CMD) &&
> +        }
> +        if (is_write) {
> +            /* set block interrupt at end of each block transfer */
> +            if (s->hbct && s->datacnt % s->hbct == 0 &&
>                  (s->config & SDHCFG_BLOCK_IRPT_EN)) {
>                  s->status |= SDHSTS_BLOCK_IRPT;
>              }
> +            /* set data interrupt after each transfer */
> +            s->status |= SDHSTS_DATA_FLAG;
> +            if (s->config & SDHCFG_DATA_IRPT_EN) {
> +                s->status |= SDHSTS_SDIO_IRPT;
> +            }
>          }
>      }
>  
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]