From: David Brownell <[email protected]>

Get rid of some needless symbol duplication:

 - Use MMCST0_* symbols for both MMCST0 (irq status) and
   MMCIM (irq mask) registers.

 - Use MMCST0_* symbols instead of MMCSD_EVENT_* enums; the
   enum names obfuscated code with respect to chip specs.

 - Use mmc_resp_type() directly; RSP_TYPE() isn't needed.

Also:

 - Switch the MMCST0_* symbols to the more compact BIT() syntax,
   and add matching "what does this do?" comments.

 - Use the already-defined MMCCMD_* symbols, not magic numbers.

 - Remove obsolete lament about protocol layer not providing
   something which it now provides.

Minor functional changes that shouldn't affect behavior, and
were suggested by the above changes:

 - Don't enable read IRQs when writing data, and vice versa.

 - Shrink the PIO loop in the IRQ handler.

Overall, this code should now be easier to cross-check against
specs and thus more clear in several ways.

Signed-off-by: David Brownell <[email protected]>
---
 drivers/mmc/host/davinci_mmc.c |  221 +++++++++++----------------------------
 1 file changed, 65 insertions(+), 156 deletions(-)

--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -92,37 +92,23 @@
 #define MMCCLK_CLKEN          (1 << 8)
 #define MMCCLK_CLKRT_MASK     (0xFF << 0)
 
-/* DAVINCI_MMCST0 definitions */
-#define MMCST0_DATDNE         (1 << 0)
-#define MMCST0_BSYDNE         (1 << 1)
-#define MMCST0_RSPDNE         (1 << 2)
-#define MMCST0_TOUTRD         (1 << 3)
-#define MMCST0_TOUTRS         (1 << 4)
-#define MMCST0_CRCWR          (1 << 5)
-#define MMCST0_CRCRD          (1 << 6)
-#define MMCST0_CRCRS          (1 << 7)
-#define MMCST0_DXRDY          (1 << 9)
-#define MMCST0_DRRDY          (1 << 10)
-#define MMCST0_DATED          (1 << 11)
-#define MMCST0_TRNDNE         (1 << 12)
+/* IRQ bit definitions, for DAVINCI_MMCST0 and DAVINCI_MMCIM */
+#define MMCST0_DATDNE         BIT(0)   /* data done */
+#define MMCST0_BSYDNE         BIT(1)   /* busy done */
+#define MMCST0_RSPDNE         BIT(2)   /* command done */
+#define MMCST0_TOUTRD         BIT(3)   /* data read timeout */
+#define MMCST0_TOUTRS         BIT(4)   /* command response timeout */
+#define MMCST0_CRCWR          BIT(5)   /* data write CRC error */
+#define MMCST0_CRCRD          BIT(6)   /* data read CRC error */
+#define MMCST0_CRCRS          BIT(7)   /* command response CRC error */
+#define MMCST0_DXRDY          BIT(9)   /* data transmit ready (fifo empty) */
+#define MMCST0_DRRDY          BIT(10)  /* data receive ready (data in fifo)*/
+#define MMCST0_DATED          BIT(11)  /* DAT3 edge detect */
+#define MMCST0_TRNDNE         BIT(12)  /* transfer done */
 
 /* DAVINCI_MMCST1 definitions */
 #define MMCST1_BUSY           (1 << 0)
 
-/* DAVINCI_MMCIM definitions */
-#define MMCIM_EDATDNE         (1 << 0)
-#define MMCIM_EBSYDNE         (1 << 1)
-#define MMCIM_ERSPDNE         (1 << 2)
-#define MMCIM_ETOUTRD         (1 << 3)
-#define MMCIM_ETOUTRS         (1 << 4)
-#define MMCIM_ECRCWR          (1 << 5)
-#define MMCIM_ECRCRD          (1 << 6)
-#define MMCIM_ECRCRS          (1 << 7)
-#define MMCIM_EDXRDY          (1 << 9)
-#define MMCIM_EDRRDY          (1 << 10)
-#define MMCIM_EDATED          (1 << 11)
-#define MMCIM_ETRNDNE         (1 << 12)
-
 /* DAVINCI_MMCCMD definitions */
 #define MMCCMD_CMD_MASK       (0x3F << 0)
 #define MMCCMD_PPLEN          (1 << 7)
@@ -149,13 +135,6 @@
 #define MMCFIFOCTL_ACCWD_2    (2 << 3) /* access width of 2 bytes    */
 #define MMCFIFOCTL_ACCWD_1    (3 << 3) /* access width of 1 byte     */
 
-/*
- * Command types
- */
-#define DAVINCI_MMC_CMDTYPE_BC 0
-#define DAVINCI_MMC_CMDTYPE_BCR        1
-#define DAVINCI_MMC_CMDTYPE_AC 2
-#define DAVINCI_MMC_CMDTYPE_ADTC       3
 
 /* MMCSD Init clock in Hz in opendain mode */
 #define MMCSD_INIT_CLOCK               200000
@@ -227,20 +206,6 @@ struct mmc_davinci_host {
        unsigned int option_write;
 };
 
-enum mmcsdevent {
-       MMCSD_EVENT_EOFCMD = (1 << 2),
-       MMCSD_EVENT_READ = (1 << 10),
-       MMCSD_EVENT_WRITE = (1 << 9),
-       MMCSD_EVENT_ERROR_CMDCRC = (1 << 7),
-       MMCSD_EVENT_ERROR_DATACRC = ((1 << 6) | (1 << 5)),
-       MMCSD_EVENT_ERROR_CMDTIMEOUT = (1 << 4),
-       MMCSD_EVENT_ERROR_DATATIMEOUT = (1 << 3),
-       MMCSD_EVENT_CARD_EXITBUSY = (1 << 1),
-       MMCSD_EVENT_BLOCK_XFERRED = (1 << 0)
-};
-
-
-#define RSP_TYPE(x)    ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
 
 #define DAVINCI_MMCSD_READ_FIFO(pDst, pRegs, cnt) asm( \
        "       cmp     %3,#16\n" \
@@ -336,142 +301,104 @@ static void mmc_davinci_start_command(st
                struct mmc_command *cmd)
 {
        u32 cmd_reg = 0;
-       u32 resp_type = 0;
-       u32 cmd_type = 0;
        u32 im_val;
 
        dev_dbg(mmc_dev(host->mmc), "CMD%d, arg 0x%08x%s\n",
                cmd->opcode, cmd->arg,
                ({ char *s;
-               switch (RSP_TYPE(mmc_resp_type(cmd))) {
-               case RSP_TYPE(MMC_RSP_R1):
-                       s = ", R1/R1b response";
+               switch (mmc_resp_type(cmd)) {
+               case MMC_RSP_R1:
+                       s = ", R1/R5/R6/R7 response";
                        break;
-               case RSP_TYPE(MMC_RSP_R2):
+               case MMC_RSP_R1B:
+                       s = ", R1b response";
+                       break;
+               case MMC_RSP_R2:
                        s = ", R2 response";
                        break;
-               case RSP_TYPE(MMC_RSP_R3):
-                       s = ", R3 response";
+               case MMC_RSP_R3:
+                       s = ", R3/R4 response";
                        break;
                default:
-                       s = "";
+                       s = ", (R? response)";
                        break;
                }; s; }));
        host->cmd = cmd;
 
-       /* Protocol layer does not provide response type,
-        * but our hardware needs to know exact type, not just size!
-        */
-       switch (RSP_TYPE(mmc_resp_type(cmd))) {
-       case MMC_RSP_NONE:
-               /* resp 0 */
-               break;
-       case RSP_TYPE(MMC_RSP_R1):
-               resp_type = 1;
+       switch (mmc_resp_type(cmd)) {
+       case MMC_RSP_R1B:
+               /* There's some spec confusion about when R1B is
+                * allowed, but if the card doesn't issue a BUSY
+                * then it's harmless for us to allow it.
+                */
+               cmd_reg |= MMCCMD_BSYEXP;
+               /* FALLTHROUGH */
+       case MMC_RSP_R1:                /* 48 bits, CRC */
+               cmd_reg |= MMCCMD_RSPFMT_R1456;
                break;
-       case RSP_TYPE(MMC_RSP_R2):
-               resp_type = 2;
+       case MMC_RSP_R2:                /* 136 bits, CRC */
+               cmd_reg |= MMCCMD_RSPFMT_R2;
                break;
-       case RSP_TYPE(MMC_RSP_R3):
-               resp_type = 3;
+       case MMC_RSP_R3:                /* 48 bits, no CRC */
+               cmd_reg |= MMCCMD_RSPFMT_R3;
                break;
        default:
+               cmd_reg |= MMCCMD_RSPFMT_NONE;
+               dev_dbg(mmc_dev(host->mmc), "unknown resp_type %04x\n",
+                       mmc_resp_type(cmd));
                break;
        }
 
-       /* Protocol layer does not provide command type, but our hardware
-        * needs it!
-        * any data transfer means adtc type (but that information is not
-        * in command structure, so we flagged it into host struct.)
-        * However, telling bc, bcr and ac apart based on response is
-        * not foolproof:
-        * CMD0  = bc  = resp0  CMD15 = ac  = resp0
-        * CMD2  = bcr = resp2  CMD10 = ac  = resp2
-        *
-        * Resolve to best guess with some exception testing:
-        * resp0 -> bc, except CMD15 = ac
-        * rest are ac, except if opendrain
-        */
-
-       if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
-               cmd_type = DAVINCI_MMC_CMDTYPE_ADTC;
-       else if (mmc_cmd_type(cmd) == MMC_CMD_BC)
-               cmd_type = DAVINCI_MMC_CMDTYPE_BC;
-       else if (mmc_cmd_type(cmd) == MMC_CMD_BCR)
-               cmd_type = DAVINCI_MMC_CMDTYPE_BCR;
-       else
-               cmd_type = DAVINCI_MMC_CMDTYPE_AC;
-
-       /* Set command Busy or not */
-       if (cmd->flags & MMC_RSP_BUSY) {
-               /*
-                * Linux core sending BUSY which is not defined for cmd 24
-                * as per mmc standard
-                */
-               if (cmd->opcode != 24)
-                       cmd_reg = cmd_reg | (1 << 8);
-       }
-
        /* Set command index */
        cmd_reg |= cmd->opcode;
 
        /* Setting initialize clock */
        if (cmd->opcode == 0)
-               cmd_reg = cmd_reg | (1 << 14);
+               cmd_reg |= MMCCMD_INITCK;
 
        /* Set for generating DMA Xfer event */
        if ((host->do_dma == 1) && (host->data != NULL)
            && ((cmd->opcode == 18) || (cmd->opcode == 25)
                || (cmd->opcode == 24) || (cmd->opcode == 17)))
-               cmd_reg = cmd_reg | (1 << 16);
+               cmd_reg |= MMCCMD_DMATRIG;
 
        /* Setting whether command involves data transfer or not */
-       if (cmd_type == DAVINCI_MMC_CMDTYPE_ADTC)
-               cmd_reg = cmd_reg | (1 << 13);
+       if (cmd->data)
+               cmd_reg |= MMCCMD_WDATX;
 
        /* Setting whether stream or block transfer */
        if (cmd->flags & MMC_DATA_STREAM)
-               cmd_reg = cmd_reg | (1 << 12);
+               cmd_reg |= MMCCMD_STRMTP;
 
        /* Setting whether data read or write */
        if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
-               cmd_reg = cmd_reg | (1 << 11);
-
-       /* Setting response type */
-       cmd_reg = cmd_reg | (resp_type << 9);
+               cmd_reg |= MMCCMD_DTRW;
 
        if (host->bus_mode == MMC_BUSMODE_PUSHPULL)
-               cmd_reg = cmd_reg | (1 << 7);
+               cmd_reg |= MMCCMD_PPLEN;
 
        /* set Command timeout */
        writel(0xFFFF, host->base + DAVINCI_MMCTOR);
 
        /* Enable interrupt (calculate here, defer until FIFO is stuffed). */
-       im_val =  MMCSD_EVENT_EOFCMD
-               | MMCSD_EVENT_ERROR_CMDCRC
-               | MMCSD_EVENT_ERROR_DATACRC
-               | MMCSD_EVENT_ERROR_CMDTIMEOUT
-               | MMCSD_EVENT_ERROR_DATATIMEOUT;
+       im_val =  MMCST0_RSPDNE | MMCST0_CRCRS | MMCST0_TOUTRS;
        if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
-               im_val |= MMCSD_EVENT_BLOCK_XFERRED;
+               im_val |= MMCST0_DATDNE | MMCST0_CRCWR;
 
                if (!host->do_dma)
-                       im_val |= MMCSD_EVENT_WRITE;
+                       im_val |= MMCST0_DXRDY;
        } else if (host->data_dir == DAVINCI_MMC_DATADIR_READ) {
-               im_val |= MMCSD_EVENT_BLOCK_XFERRED;
+               im_val |= MMCST0_DATDNE | MMCST0_CRCRD | MMCST0_TOUTRD;
 
                if (!host->do_dma)
-                       im_val |= MMCSD_EVENT_READ;
+                       im_val |= MMCST0_DRRDY;
        }
 
        /*
-        * It is required by controoler b4 WRITE command that
+        * Before non-DMA WRITE commands the controller needs priming:
         * FIFO should be populated with 32 bytes
         */
-       if ((host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
-                       && (cmd_type == DAVINCI_MMC_CMDTYPE_ADTC)
-                       && (host->do_dma != 1))
-               /* Fill the FIFO for Tx */
+       if (!host->do_dma && (host->data_dir == DAVINCI_MMC_DATADIR_WRITE))
                davinci_fifo_data_trans(host, 32);
 
        writel(cmd->arg, host->base + DAVINCI_MMCARGHL);
@@ -967,8 +894,7 @@ static void mmc_davinci_set_ios(struct m
                /* Send clock cycles, poll completion */
                writel(0, host->base + DAVINCI_MMCARGHL);
                writel(MMCCMD_INITCK, host->base + DAVINCI_MMCCMD);
-               while (!(readl(host->base + DAVINCI_MMCST0) &
-                               MMCSD_EVENT_EOFCMD))
+               while (!(readl(host->base + DAVINCI_MMCST0) & MMCST0_RSPDNE))
                        cpu_relax();
        }
 
@@ -1040,35 +966,18 @@ static inline int handle_core_command(
 {
        int end_command = 0;
        int end_transfer = 0;
-       unsigned int qstatus;
-
-       qstatus = status;
-       while (1) {
-               if ((status & MMCSD_EVENT_WRITE) &&
-                               (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
-                               && (host->bytes_left > 0)) {
-                       /* Buffer almost empty */
-                       davinci_fifo_data_trans(host, rw_threshold);
-               }
+       unsigned int qstatus = status;
 
-               if ((status & MMCSD_EVENT_READ) &&
-                               (host->data_dir == DAVINCI_MMC_DATADIR_READ)
-                               && (host->bytes_left > 0)) {
-                       /* Buffer almost empty */
-                       davinci_fifo_data_trans(host, rw_threshold);
-               }
+       /* handle FIFO first when using PIO for data */
+       while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) {
+               davinci_fifo_data_trans(host, rw_threshold);
                status = readl(host->base + DAVINCI_MMCST0);
                if (!status)
                        break;
                qstatus |= status;
-               if (host->data == NULL) {
-                       dev_dbg(mmc_dev(host->mmc), "Status is %x at end of "
-                               "ISR when host->data is NULL", status);
-                       break;
-               }
        }
 
-       if (qstatus & MMCSD_EVENT_BLOCK_XFERRED) {
+       if (qstatus & MMCST0_DATDNE) {
                /* Block sent/received */
                if (host->data != NULL) {
                        if ((host->do_dma == 0) && (host->bytes_left > 0)) {
@@ -1084,7 +993,7 @@ static inline int handle_core_command(
                }
        }
 
-       if (qstatus & MMCSD_EVENT_ERROR_DATATIMEOUT) {
+       if (qstatus & MMCST0_TOUTRD) {
                /* Data timeout */
                if (host->data) {
                        host->data->error = -ETIMEDOUT;
@@ -1098,7 +1007,7 @@ static inline int handle_core_command(
                }
        }
 
-       if (qstatus & MMCSD_EVENT_ERROR_DATACRC) {
+       if (qstatus & (MMCST0_CRCWR | MMCST0_CRCRD)) {
                u32 temp;
                /* DAT line portion is disabled and in reset state */
                temp = readl(host->base + DAVINCI_MMCCTL);
@@ -1122,7 +1031,7 @@ static inline int handle_core_command(
                }
        }
 
-       if (qstatus & MMCSD_EVENT_ERROR_CMDTIMEOUT) {
+       if (qstatus & MMCST0_TOUTRS) {
                if (host->do_dma)
                        davinci_abort_dma(host);
 
@@ -1136,7 +1045,7 @@ static inline int handle_core_command(
                }
        }
 
-       if (qstatus & MMCSD_EVENT_ERROR_CMDCRC) {
+       if (qstatus & MMCST0_CRCRS) {
                /* Command CRC error */
                dev_dbg(mmc_dev(host->mmc), "Command CRC error\n");
                if (host->cmd) {
@@ -1147,7 +1056,7 @@ static inline int handle_core_command(
                }
        }
 
-       if (qstatus & MMCSD_EVENT_EOFCMD) {
+       if (qstatus & MMCST0_RSPDNE) {
                /* End of command phase */
                end_command = 1;
        }

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to