msm_shared: mmc: Add BAM and DML support.
Change-Id: I81fb4105a313cb6d555587418e806c5f22dcb37b
diff --git a/platform/copper/include/platform/iomap.h b/platform/copper/include/platform/iomap.h
index f29cccd..d099e3d 100644
--- a/platform/copper/include/platform/iomap.h
+++ b/platform/copper/include/platform/iomap.h
@@ -30,6 +30,7 @@
#define _PLATFORM_MSMCOPPER_IOMAP_H_
#define SDRAM_START_ADDR 0x00000000
+#define SDRAM_SEC_BANK_START_ADDR 0x10000000
#define MSM_SHARED_BASE 0x0FA00000
@@ -41,15 +42,22 @@
#define APCS_APC_KPSS_PLL_BASE (KPSS_BASE + 0x0000A000)
#define APCS_KPSS_CFG_BASE (KPSS_BASE + 0x00010000)
#define APCS_KPSS_WDT_BASE (KPSS_BASE + 0x00017000)
-#define KPSS_APCS_QTMR_AC_BASE (KPSS_BASE + 0x20000)
-#define KPSS_APCS_F0_QTMR_V1_BASE (KPSS_BASE + 0x21000)
-#define QTMR_BASE KPSS_APCS_F0_QTMR_V1_BASE
#define PERIPH_SS_BASE 0xF9800000
+
+#define MSM_SDC1_BAM_BASE (PERIPH_SS_BASE + 0x00004000)
#define MSM_SDC1_BASE (PERIPH_SS_BASE + 0x00024000)
+#define MSM_SDC1_DML_BASE (PERIPH_SS_BASE + 0x00024800)
+#define MSM_SDC3_BAM_BASE (PERIPH_SS_BASE + 0x00044000)
#define MSM_SDC3_BASE (PERIPH_SS_BASE + 0x00064000)
+#define MSM_SDC3_DML_BASE (PERIPH_SS_BASE + 0x00064800)
+#define MSM_SDC2_BAM_BASE (PERIPH_SS_BASE + 0x00084000)
#define MSM_SDC2_BASE (PERIPH_SS_BASE + 0x000A4000)
+#define MSM_SDC2_DML_BASE (PERIPH_SS_BASE + 0x000A4800)
+#define MSM_SDC4_BAM_BASE (PERIPH_SS_BASE + 0x000C4000)
#define MSM_SDC4_BASE (PERIPH_SS_BASE + 0x000E4000)
+#define MSM_SDC4_DML_BASE (PERIPH_SS_BASE + 0x000E4800)
+
#define BLSP1_UART0_BASE (PERIPH_SS_BASE + 0x0011D000)
#define BLSP1_UART1_BASE (PERIPH_SS_BASE + 0x0011E000)
#define BLSP1_UART2_BASE (PERIPH_SS_BASE + 0x0011F000)
@@ -70,7 +78,6 @@
#define MPM2_MPM_CTRL_BASE 0xFC4A1000
-
/* Clock control registers */
/* GPLL */
diff --git a/platform/msm_shared/include/mmc_dml.h b/platform/msm_shared/include/mmc_dml.h
new file mode 100644
index 0000000..3941bf6
--- /dev/null
+++ b/platform/msm_shared/include/mmc_dml.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MMC_DML_H__
+#define __MMC_DML_H__
+
+#include <platform/iomap.h>
+
+#define SDCC_DML_CONFIG(base) (0x00 + base)
+#define SDCC_CONSUMER_CRCI_SEL_SHIFT 2
+#define SDCC_PRODUCER_CRCI_SEL_SHIFT 0
+#define SDCC_PRODUCER_TRANS_END_EN_SHIFT 4
+#define SDCC_BYPASS_SHIFT 16
+#define SDCC_DIRECT_MODE_SHIFT 17
+#define SDCC_INFINITE_CONS_TRANS_SHIFT 18
+
+#define SDCC_DML_STATUS(base) (0x04 + base)
+#define SDCC_DML_PRODUCER_IDLE_SHIFT 0
+#define SDCC_DML_CONSUMER_IDLE_SHIFT 16
+
+#define SDCC_DML_SW_RESET(base) (0x08 + base)
+#define SDCC_DML_PRODUCER_START(base) (0x0C + base)
+#define SDCC_DML_CONSUMER_START(base) (0x10 + base)
+#define SDCC_DML_PRODUCER_PIPE_LOGICAL_SIZE(base) (0x14 + base)
+#define SDCC_DML_CONSUMER_PIPE_LOGICAL_SIZE(base) (0x18 + base)
+
+#define SDCC_DML_PIPE_ID(base) (0x1C + base)
+#define SDCC_CONSUMER_PIPE_ID_SHIFT 16
+#define SDCC_PRODUCER_PIPE_ID_SHIFT 0
+
+#define SDCC_DML_PRODUCER_BAM_BLOCK_SIZE(base) (0x24 + base)
+#define SDCC_DML_PRODUCER_BAM_TRANS_SIZE(base) (0x28 + base)
+
+#endif
diff --git a/platform/msm_shared/mmc.c b/platform/msm_shared/mmc.c
index e04c64f..803a1e2 100644
--- a/platform/msm_shared/mmc.c
+++ b/platform/msm_shared/mmc.c
@@ -39,6 +39,11 @@
#include "adm.h"
#endif
+#if MMC_BOOT_BAM
+#include "bam.h"
+#include "mmc_dml.h"
+#endif
+
#ifndef NULL
#define NULL 0
#endif
@@ -46,7 +51,7 @@
#define MMC_BOOT_DATA_READ 0
#define MMC_BOOT_DATA_WRITE 1
-static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+static unsigned int mmc_boot_data_transfer(unsigned int *data_ptr,
unsigned int data_len,
unsigned char direction);
@@ -56,6 +61,32 @@
static unsigned int mmc_boot_fifo_write(unsigned int *data_ptr,
unsigned int data_len);
+static unsigned int mmc_boot_status_error(unsigned mmc_status);
+
+#if MMC_BOOT_BAM
+
+void mmc_boot_dml_init();
+
+static void mmc_boot_dml_producer_trans_init(unsigned trans_end,
+ unsigned size);
+
+static void mmc_boot_dml_consumer_trans_init();
+
+static uint32_t mmc_boot_dml_chk_producer_idle();
+
+static void mmc_boot_dml_wait_producer_idle();
+static void mmc_boot_dml_wait_consumer_idle();
+static void mmc_boot_dml_reset();
+static int mmc_bam_init(uint32_t bam_base);
+static int mmc_bam_transfer_data();
+static unsigned int
+mmc_boot_bam_setup_desc(unsigned int *data_ptr,
+ unsigned int data_len, unsigned char direction);
+
+
+#endif
+
+
#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
/* data access time unit in ns */
@@ -78,6 +109,30 @@
static unsigned char ext_csd_buf[512];
static unsigned char wp_status_buf[8];
+#if MMC_BOOT_BAM
+
+static uint32_t mmc_sdc_bam_base[] =
+ { MSM_SDC1_BAM_BASE, MSM_SDC2_BAM_BASE, MSM_SDC3_BAM_BASE, MSM_SDC4_BAM_BASE };
+
+static uint32_t mmc_sdc_dml_base[] =
+ { MSM_SDC1_DML_BASE, MSM_SDC2_DML_BASE, MSM_SDC3_DML_BASE, MSM_SDC4_DML_BASE };
+
+uint32_t dml_base;
+static struct bam_instance bam;
+
+#define MMC_BOOT_BAM_FIFO_SIZE 100
+
+#define MMC_BOOT_BAM_READ_PIPE_INDEX 0
+#define MMC_BOOT_BAM_WRITE_PIPE_INDEX 1
+
+#define MMC_BOOT_BAM_READ_PIPE 0
+#define MMC_BOOT_BAM_WRITE_PIPE 1
+
+/* Align at BAM_DESC_SIZE boundary */
+static struct bam_desc desc_fifo[MMC_BOOT_BAM_FIFO_SIZE] __attribute__ ((aligned(BAM_DESC_SIZE)));
+
+#endif
+
int mmc_clock_enable_disable(unsigned id, unsigned enable);
int mmc_clock_get_rate(unsigned id);
int mmc_clock_set_rate(unsigned id, unsigned rate);
@@ -1071,12 +1126,17 @@
MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (512 <<
MMC_BOOT_MCI_BLKSIZE_POS);
-#if MMC_BOOT_ADM
+#if MMC_BOOT_ADM || MMC_BOOT_BAM
mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif
writel(mmc_reg, MMC_BOOT_MCI_DATA_CTL);
+#if MMC_BOOT_BAM
+ /* Setup SDCC BAM descriptors for Read operation. */
+ mmc_ret = mmc_boot_bam_setup_desc(mmc_ptr, 512, MMC_BOOT_DATA_READ);
+#endif
+
memset((struct mmc_boot_command *)&cmd, 0,
sizeof(struct mmc_boot_command));
/* CMD8 */
@@ -1092,7 +1152,10 @@
}
/* Read the transfer data from SDCC FIFO. */
- mmc_ret = mmc_boot_fifo_data_transfer(mmc_ptr, 512, MMC_BOOT_DATA_READ);
+ mmc_ret = mmc_boot_data_transfer(mmc_ptr, 512, MMC_BOOT_DATA_READ);
+
+ /* Reset DPSM */
+ writel(0, MMC_BOOT_MCI_DATA_CTL);
return mmc_ret;
}
@@ -1361,6 +1424,10 @@
/* Write the total size of the transfer data to MCI_DATA_LENGTH register */
writel(data_len, MMC_BOOT_MCI_DATA_LENGTH);
+#if MMC_BOOT_BAM
+ mmc_boot_bam_setup_desc(in, data_len, MMC_BOOT_DATA_WRITE);
+#endif
+
/* Send command to the card/device in order to start the write data xfer.
The possible commands are CMD24/25/53/60/61 */
mmc_ret = mmc_boot_send_write_command(card, xfer_type, addr);
@@ -1382,7 +1449,7 @@
/* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */
-#if MMC_BOOT_ADM
+#if MMC_BOOT_ADM || MMC_BOOT_BAM
mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif
@@ -1393,7 +1460,7 @@
/* write data to FIFO */
mmc_ret =
- mmc_boot_fifo_data_transfer(in, data_len, MMC_BOOT_DATA_WRITE);
+ mmc_boot_data_transfer(in, data_len, MMC_BOOT_DATA_WRITE);
if (mmc_ret != MMC_BOOT_E_SUCCESS) {
dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
@@ -1438,6 +1505,14 @@
}
while (1);
+#if MMC_BOOT_BAM
+ /* Wait for DML trasaction to end */
+ mmc_boot_dml_wait_consumer_idle();
+#endif
+
+ /* Reset DPSM */
+ writel(0, MMC_BOOT_MCI_DATA_CTL);
+
return MMC_BOOT_E_SUCCESS;
}
@@ -1619,7 +1694,7 @@
/* If DMA is to be used, Set DM_ENABLE bit to 1 */
-#if MMC_BOOT_ADM
+#if MMC_BOOT_ADM || MMC_BOOT_BAM
mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif
@@ -1628,6 +1703,10 @@
mmc_reg |= (card->rd_block_len << MMC_BOOT_MCI_BLKSIZE_POS);
writel(mmc_reg, MMC_BOOT_MCI_DATA_CTL);
+#if MMC_BOOT_BAM
+ /* Setup SDCC FIFO descriptors for Read operation. */
+ mmc_ret = mmc_boot_bam_setup_desc(out, data_len, MMC_BOOT_DATA_READ);
+#endif
/* Send command to the card/device in order to start the read data
transfer. Possible commands: CMD17/18/53/60/61. */
mmc_ret = mmc_boot_send_read_command(card, xfer_type, addr);
@@ -1639,8 +1718,7 @@
}
/* Read the transfer data from SDCC FIFO. */
- mmc_ret =
- mmc_boot_fifo_data_transfer(out, data_len, MMC_BOOT_DATA_READ);
+ mmc_ret = mmc_boot_data_transfer(out, data_len, MMC_BOOT_DATA_READ);
if (mmc_ret != MMC_BOOT_E_SUCCESS) {
dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
@@ -1661,6 +1739,9 @@
}
}
+ /* Reset DPSM */
+ writel(0, MMC_BOOT_MCI_DATA_CTL);
+
return MMC_BOOT_E_SUCCESS;
}
@@ -2143,6 +2224,12 @@
return MMC_BOOT_E_FAILURE;
}
+#if MMC_BOOT_BAM
+
+ mmc_ret = mmc_bam_init(mmc_sdc_bam_base[slot - 1]);
+ dml_base = mmc_sdc_dml_base[slot - 1];
+#endif
+
/* Initialize and identify cards connected to host */
mmc_ret = mmc_boot_init_and_identify_cards(&mmc_host, &mmc_card);
if (mmc_ret != MMC_BOOT_E_SUCCESS) {
@@ -2235,7 +2322,7 @@
MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (data_len <<
MMC_BOOT_MCI_BLKSIZE_POS);
-#if MMC_BOOT_ADM
+#if MMC_BOOT_ADM || MMC_BOOT_BAM
mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif
@@ -2257,7 +2344,7 @@
/* Read the transfer data from SDCC FIFO. */
mmc_ret =
- mmc_boot_fifo_data_transfer(out, data_len, MMC_BOOT_DATA_READ);
+ mmc_boot_data_transfer(out, data_len, MMC_BOOT_DATA_READ);
if (mmc_ret != MMC_BOOT_E_SUCCESS) {
dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
@@ -2468,7 +2555,7 @@
* Read/write data from/to SDC FIFO.
*/
static unsigned int
-mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+mmc_boot_data_transfer(unsigned int *data_ptr,
unsigned int data_len, unsigned char direction)
{
unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
@@ -2491,6 +2578,9 @@
dprintf(CRITICAL, "MMC ADM transfer error: %d\n", ret);
mmc_ret = MMC_BOOT_E_FAILURE;
}
+
+#elif MMC_BOOT_BAM
+ mmc_ret = mmc_bam_transfer_data(data_ptr, data_len, direction);
#else
if (direction == MMC_BOOT_DATA_READ) {
@@ -2499,6 +2589,7 @@
mmc_ret = mmc_boot_fifo_write(data_ptr, data_len);
}
#endif
+
return mmc_ret;
}
@@ -2830,3 +2921,273 @@
{
return &mmc_card;
}
+
+#if MMC_BOOT_BAM
+
+void mmc_boot_dml_init()
+{
+ uint32_t val = 0;
+
+ /* Initialize s/w reset for DML core */
+ mmc_boot_dml_reset();
+
+ /* Program DML config:
+ * 1. Disable producer and consumer CRCI.
+ * 2. Set Bypass mode for the DML for Direct access.
+ */
+ val = 0;
+ val |= 1 >> SDCC_BYPASS_SHIFT;
+ writel(val, SDCC_DML_CONFIG(dml_base));
+
+ /* Program consumer logic size:
+ * This is for handshaking between the BAM and the DML blocks.
+ */
+ writel(4096, SDCC_DML_CONSUMER_PIPE_LOGICAL_SIZE(dml_base));
+
+ /* Program producer logic size
+ * This is for handshaking between the BAM and the DML blocks.
+ */
+ writel(4096, SDCC_DML_PRODUCER_PIPE_LOGICAL_SIZE(dml_base));
+
+
+ /* Write the pipe id numbers. */
+ val = 0;
+ val |= bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].pipe_num << SDCC_PRODUCER_PIPE_ID_SHIFT;
+ val |= bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].pipe_num << SDCC_CONSUMER_PIPE_ID_SHIFT;
+
+ writel(val, SDCC_DML_PIPE_ID(dml_base));
+
+}
+
+/* Function to set up SDCC dml for System producer transaction. */
+static void mmc_boot_dml_consumer_trans_init()
+{
+ uint32_t val = 0;
+
+ val = 0 << SDCC_PRODUCER_CRCI_SEL_SHIFT;
+ val |= 1 << SDCC_CONSUMER_CRCI_SEL_SHIFT;
+ writel(val, SDCC_DML_CONFIG(dml_base));
+
+
+ /* Start the consumer transaction */
+ writel(1, SDCC_DML_CONSUMER_START(dml_base));
+
+}
+
+/* Function to set up SDCC dml for System consumer transaction.
+ * trans_end: 1: Assert DML trasaction signal
+ * at the end of transaction.
+ * 0: Do not assert DML transaction signal.
+ * size: Transaction size
+ */
+static void mmc_boot_dml_producer_trans_init(unsigned trans_end,
+ unsigned size)
+{
+ uint32_t val = 0;
+
+ val = 1 << SDCC_PRODUCER_CRCI_SEL_SHIFT;
+ val |= 0 << SDCC_CONSUMER_CRCI_SEL_SHIFT;
+ val |= trans_end << SDCC_PRODUCER_TRANS_END_EN_SHIFT;
+ writel(val, SDCC_DML_CONFIG(dml_base));
+
+ /* Set block size */
+ writel(BLOCK_SIZE, SDCC_DML_PRODUCER_BAM_BLOCK_SIZE(dml_base));
+
+ /* Write transaction size */
+ writel(size, SDCC_DML_PRODUCER_BAM_TRANS_SIZE(dml_base));
+
+ /* Start the producer transaction */
+ writel(1, SDCC_DML_PRODUCER_START(dml_base));
+}
+
+/* Function to check producer idle status of the DML.
+ * return value: 1: Producer is idle
+ * 0: Producer is busy
+ */
+static uint32_t mmc_boot_dml_chk_producer_idle()
+{
+ uint32_t val = 0;
+
+ val = readl(SDCC_DML_STATUS(dml_base));
+
+ /* Read only the producer idle status */
+ val &= (1 << SDCC_DML_PRODUCER_IDLE_SHIFT);
+
+ return val;
+}
+
+/* Function to clear transaction complete flag */
+static void mmc_boot_dml_clr_trans_complete()
+{
+ uint32_t val;
+
+ val = readl(SDCC_DML_CONFIG(dml_base));
+
+ val &= ~(1 << SDCC_PRODUCER_TRANS_END_EN_SHIFT);
+ writel(val, SDCC_DML_CONFIG(dml_base));
+}
+
+/* Blocking function to wait until DML is idle. */
+static void mmc_boot_dml_wait_producer_idle()
+{
+ while(!(readl(SDCC_DML_STATUS(dml_base)) & 1));
+}
+
+/* Blocking function to wait until DML is idle. */
+static void mmc_boot_dml_wait_consumer_idle()
+{
+ while(!(readl(SDCC_DML_STATUS(dml_base)) & (1 << SDCC_DML_CONSUMER_IDLE_SHIFT)));
+}
+
+/* Initialize S/W reset */
+static void mmc_boot_dml_reset()
+{
+ /* Initialize s/w reset for DML core */
+ writel(1, SDCC_DML_SW_RESET(dml_base));
+
+}
+
+static int mmc_bam_init(uint32_t bam_base)
+{
+
+ uint32_t mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ bam.base = bam_base;
+ /* Read pipe parameter initializations. */
+ bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].pipe_num = MMC_BOOT_BAM_READ_PIPE;
+ /* System consumer */
+ bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].trans_type = BAM2SYS;
+ /* Set the descriptor FIFO start ptr */
+ bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].fifo.head = desc_fifo;
+ /* Set the descriptor FIFO lengths */
+ bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].fifo.size = MMC_BOOT_BAM_FIFO_SIZE;
+
+ /* Write pipe parameter initializations.*/
+ bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].pipe_num = MMC_BOOT_BAM_WRITE_PIPE;
+ /* System producer */
+ bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].trans_type = SYS2BAM;
+ /* Write fifo uses the same fifo as read */
+ bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].fifo.head = desc_fifo;
+ /* Set the descriptor FIFO lengths */
+ bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].fifo.size = MMC_BOOT_BAM_FIFO_SIZE;
+
+ /* Programs the minimum threshold for BAM transfer*/
+ bam.threshold = BLOCK_SIZE;
+
+ /* Initialize MMC BAM */
+ bam_init(&bam);
+
+ /* Initialize BAM MMC read pipe */
+ bam_sys_pipe_init(&bam, MMC_BOOT_BAM_READ_PIPE_INDEX);
+
+ mmc_ret = bam_pipe_fifo_init(&bam, bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].pipe_num);
+
+ if (mmc_ret)
+ {
+ dprintf(CRITICAL, "MMC: BAM Read pipe fifo init error\n");
+ goto mmc_bam_init_error;
+ }
+
+ /* Initialize BAM MMC write pipe */
+ bam_sys_pipe_init(&bam, MMC_BOOT_BAM_WRITE_PIPE_INDEX);
+
+ mmc_ret = bam_pipe_fifo_init(&bam, bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].pipe_num);
+
+ if (mmc_ret)
+ {
+ dprintf(CRITICAL, "MMC: BAM Write pipe fifo init error\n");
+ goto mmc_bam_init_error;
+ }
+
+ mmc_boot_dml_init();
+
+ mmc_bam_init_error:
+
+ return mmc_ret;
+}
+
+static int mmc_bam_transfer_data(unsigned int *data_ptr,
+ unsigned int data_len,
+ unsigned int dir)
+{
+ uint32_t mmc_ret;
+ uint32_t offset;
+
+ mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ if(dir == MMC_BOOT_DATA_READ)
+ {
+ /* Check BAM IRQ status reg to verify the desc has been processed */
+ mmc_ret = bam_wait_for_interrupt(&bam,
+ MMC_BOOT_BAM_READ_PIPE_INDEX, P_PRCSD_DESC_EN_MASK);
+
+ if (mmc_ret != BAM_RESULT_SUCCESS)
+ {
+ dprintf(CRITICAL, "BAM transfer error \n");
+ mmc_ret = MMC_BOOT_E_FAILURE;
+ goto mmc_bam_transfer_err;
+ }
+
+ mmc_boot_dml_wait_producer_idle();
+
+ /* Update BAM pipe fifo offsets */
+ offset = bam_read_offset_update(&bam, MMC_BOOT_BAM_READ_PIPE_INDEX);
+
+ /* Reset DPSM */
+ writel(0, MMC_BOOT_MCI_DATA_CTL);
+
+ dprintf(SPEW, "Offset value is %d \n", offset);
+ }
+ else
+ {
+ /* Check BAM IRQ status reg to verify the desc has been processed */
+ mmc_ret = bam_wait_for_interrupt(&bam,
+ MMC_BOOT_BAM_WRITE_PIPE_INDEX, P_TRNSFR_END_EN_MASK);
+
+ if (mmc_ret != BAM_RESULT_SUCCESS)
+ {
+ dprintf(CRITICAL, "BAM transfer error \n");
+ mmc_ret = MMC_BOOT_E_FAILURE;
+ goto mmc_bam_transfer_err;
+ }
+
+ /* Update BAM pipe fifo offsets */
+ offset = bam_read_offset_update(&bam, MMC_BOOT_BAM_WRITE_PIPE_INDEX);
+
+ dprintf(SPEW, "Offset value is %d \n", offset);
+ }
+
+mmc_bam_transfer_err:
+
+ return mmc_ret;
+}
+
+static unsigned int
+mmc_boot_bam_setup_desc(unsigned int *data_ptr,
+ unsigned int data_len,
+ unsigned char direction)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ if (direction == MMC_BOOT_DATA_READ)
+ {
+ mmc_boot_dml_producer_trans_init(1, data_len);
+ mmc_ret = bam_add_desc(&bam, MMC_BOOT_BAM_READ_PIPE_INDEX,
+ (unsigned char *)data_ptr, data_len);
+ }
+ else
+ {
+ mmc_boot_dml_consumer_trans_init();
+ mmc_ret = bam_add_desc(&bam, MMC_BOOT_BAM_WRITE_PIPE_INDEX,
+ (unsigned char *)data_ptr, data_len);
+ }
+
+ /* Update return value enums */
+ if (mmc_ret != BAM_RESULT_SUCCESS)
+ {
+ dprintf(CRITICAL, "MMC BAM transfer error: %d\n", mmc_ret);
+ mmc_ret = MMC_BOOT_E_FAILURE;
+ }
+}
+
+#endif
diff --git a/project/copper.mk b/project/copper.mk
index e6e7b40..7b97869 100644
--- a/project/copper.mk
+++ b/project/copper.mk
@@ -12,3 +12,4 @@
DEFINES += WITH_DEBUG_UART=1
#DEFINES += WITH_DEBUG_FBCON=1
DEFINES += DEVICE_TREE=1
+DEFINES += MMC_BOOT_BAM=1