if (cadence_nand_read_bch_caps(cdns_ctrl))
                return -EIO;
 
+#ifndef CONFIG_64BIT
+       if (cdns_ctrl->caps2.data_dma_width == 8) {
+               dev_err(cdns_ctrl->dev,
+                       "cannot access 64-bit dma on !64-bit architectures");
+               return -EIO;
+       }
+#endif
+
        /*
         * Set IO width access to 8.
         * It is because during SW device discovering width access
                return status;
 
        if (!cdns_ctrl->caps1->has_dma) {
-               int len_in_words = len >> 2;
+               u8 data_dma_width = cdns_ctrl->caps2.data_dma_width;
+
+               int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3;
 
                /* read alingment data */
-               ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words);
+               if (data_dma_width == 4)
+                       ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words);
+#ifdef CONFIG_64BIT
+               else
+                       readsq(cdns_ctrl->io.virt, buf, len_in_words);
+#endif
+
                if (sdma_size > len) {
+                       int read_bytes = (data_dma_width == 4) ?
+                               len_in_words << 2 : len_in_words << 3;
+
                        /* read rest data from slave DMA interface if any */
-                       ioread32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf,
-                                    sdma_size / 4 - len_in_words);
+                       if (data_dma_width == 4)
+                               ioread32_rep(cdns_ctrl->io.virt,
+                                            cdns_ctrl->buf,
+                                            sdma_size / 4 - len_in_words);
+#ifdef CONFIG_64BIT
+                       else
+                               readsq(cdns_ctrl->io.virt, cdns_ctrl->buf,
+                                      sdma_size / 8 - len_in_words);
+#endif
+
                        /* copy rest of data */
-                       memcpy(buf + (len_in_words << 2), cdns_ctrl->buf,
-                              len - (len_in_words << 2));
+                       memcpy(buf + read_bytes, cdns_ctrl->buf,
+                              len - read_bytes);
                }
                return 0;
        }
                return status;
 
        if (!cdns_ctrl->caps1->has_dma) {
-               int len_in_words = len >> 2;
+               u8 data_dma_width = cdns_ctrl->caps2.data_dma_width;
+
+               int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3;
+
+               if (data_dma_width == 4)
+                       iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words);
+#ifdef CONFIG_64BIT
+               else
+                       writesq(cdns_ctrl->io.virt, buf, len_in_words);
+#endif
 
-               iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words);
                if (sdma_size > len) {
+                       int written_bytes = (data_dma_width == 4) ?
+                               len_in_words << 2 : len_in_words << 3;
+
                        /* copy rest of data */
-                       memcpy(cdns_ctrl->buf, buf + (len_in_words << 2),
-                              len - (len_in_words << 2));
+                       memcpy(cdns_ctrl->buf, buf + written_bytes,
+                              len - written_bytes);
+
                        /* write all expected by nand controller data */
-                       iowrite32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf,
-                                     sdma_size / 4 - len_in_words);
+                       if (data_dma_width == 4)
+                               iowrite32_rep(cdns_ctrl->io.virt,
+                                             cdns_ctrl->buf,
+                                             sdma_size / 4 - len_in_words);
+#ifdef CONFIG_64BIT
+                       else
+                               writesq(cdns_ctrl->io.virt, cdns_ctrl->buf,
+                                       sdma_size / 8 - len_in_words);
+#endif
                }
 
                return 0;