/* * (C) Copyright Mindspeed Technologies Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #if defined(CONFIG_COMCERTO_1000) #define MDMA_GBL_CTRL_CFG *((volatile u32 *)(MDMA_BASEADDR + 0x0)) #define MDMA_TX1_PATH_HEAD *((volatile u32 *)(MDMA_BASEADDR + 0x4)) #define MDMA_TX1_PATH_CTR *((volatile u32 *)(MDMA_BASEADDR + 0x8)) #define MDMA_RX1_PATH_HEAD *((volatile u32 *)(MDMA_BASEADDR + 0x14)) #define MDMA_RX1_PATH_CTR *((volatile u32 *)(MDMA_BASEADDR + 0x18)) #define MDMA_INT_MASK_REG *((volatile u32 *)(MDMA_BASEADDR + 0x28)) #define MDMA_INT_STATUS_REG0 *((volatile u32 *)(MDMA_BASEADDR + 0x2c)) #define MDMA_INT_STATUS_REG1 *((volatile u32 *)(MDMA_BASEADDR + 0x30)) typedef struct mdma_desc_s { u32 dataBufAddr; u32 control; u32 msg1; u32 msg2; } mdma_desc_t; /***************************************************************************** * Function: mdma_memcpy * Desction: * Implemenation of memcpy function using MDMA. * No CRC mechanism supported in C1K. * Paramters: * src: Source address * dst: Destination address * len: length of the data to be copied. * crc: Not used *****************************************************************************/ int mdma_memcpy(void *src, void *dst, int len, unsigned int *crc) { u32 stat; int i; unsigned char temp1[64]; unsigned char temp2[64]; //descriptor memset to zero for(i=0; i < 64; i++) { temp1[i] = 0; temp2[i] = 0; } len = len - (len % 8); //Disable MDMA MDMA_GBL_CTRL_CFG = __cpu_to_le32(0); //Make it 16byte align mdma_desc_t *txDesc = (mdma_desc_t *)(((u32)(temp1 + 16)) & ~0xf); mdma_desc_t *rxDesc = (mdma_desc_t *)(((u32)(temp2 + 16)) & ~0xf); txDesc->dataBufAddr = __cpu_to_le32((u32)src); txDesc->control = __cpu_to_le32((u32)(0x41002000 | (len & 0x1fff))); txDesc->msg1 = txDesc->msg2 = __cpu_to_le32(0); MDMA_TX1_PATH_HEAD = __cpu_to_le32((u32)txDesc); MDMA_TX1_PATH_CTR = __cpu_to_le32(1); rxDesc->dataBufAddr = __cpu_to_le32((u32)dst); rxDesc->control = __cpu_to_le32((u32)(0x41002000 | (len & 0x1fff))); rxDesc->msg1 = rxDesc->msg2 = __cpu_to_le32(0); MDMA_RX1_PATH_HEAD = __cpu_to_le32((u32)rxDesc); MDMA_RX1_PATH_CTR = __cpu_to_le32(1); MDMA_INT_MASK_REG = __cpu_to_le32(0); MDMA_GBL_CTRL_CFG = __cpu_to_le32(1); //Enable MDMA /* wait until dma done */ while((stat = __le32_to_cpu(MDMA_RX1_PATH_CTR)) != 0); //Memcpy done, disable MDMA MDMA_GBL_CTRL_CFG = __cpu_to_le32(0); return 0; } #elif defined(CONFIG_COMCERTO_100) #define MDMA_MMFIFO_START *((volatile u32 *)(MDMA_BASEADDR + 0x100)) #define MDMA_MMFIFO_HEADPTR *((volatile u32 *)(MDMA_BASEADDR + 0x104)) #define MDMA_MMFIFO_LOCK_TSFR_SIZE *((volatile u32 *)(MDMA_BASEADDR + 0x108)) #define MDMA_MMFIFO_SOFT_RESET *((volatile u32 *)(MDMA_BASEADDR + 0x120)) #define MDMA_FIFOMM_START *((volatile u32 *)(MDMA_BASEADDR + 0x180)) #define MDMA_FIFOMM_HEADPTR *((volatile u32 *)(MDMA_BASEADDR + 0x184)) #define MDMA_FIFOMM_LOCK_TSFR_SIZE *((volatile u32 *)(MDMA_BASEADDR + 0x188)) #define MDMA_FIFOMM_SOFT_RESET *((volatile u32 *)(MDMA_BASEADDR + 0x1A0)) typedef struct mdma_bPtr_s { u32 Bpointer; u32 Bcontrol; }mdma_bPtr_t; typedef struct mdma_Fdesc_s { u32 Fnext; u32 Fsystem; u32 Fstatus; u32 Fcontrol; mdma_bPtr_t Bdesc; }mdma_Fdesc_t; int mdma_memcpy(void *src, void *dst, int len, unsigned int *crc) { unsigned char temp1[64]; unsigned char temp2[64]; volatile unsigned int val; int i; //Make it 16byte align mdma_Fdesc_t *mmfifo = (mdma_Fdesc_t *)(((u32)(temp1 + 16)) & ~0xf); mdma_Fdesc_t *fifomm = (mdma_Fdesc_t *)(((u32)(temp2 + 16)) & ~0xf); //descriptor memset to zero for(i=0; i < 64; i++) { temp1[i] = 0; temp2[i] = 0; } /* memory to FIFO */ mmfifo->Fnext = __cpu_to_le32(0x0); mmfifo->Fsystem = __cpu_to_le32(0); mmfifo->Fstatus = __cpu_to_le32(0); mmfifo->Fcontrol = __cpu_to_le32(0x83); mmfifo->Bdesc.Bpointer = __cpu_to_le32((u32)src); mmfifo->Bdesc.Bcontrol = __cpu_to_le32((0x10000 | (len & 0xffff))); /* FIFO to memory */ fifomm->Fnext = __cpu_to_le32(0x0); fifomm->Fsystem = __cpu_to_le32(0x0); fifomm->Fstatus = __cpu_to_le32(0x0); fifomm->Fcontrol = __cpu_to_le32(0x83); fifomm->Bdesc.Bpointer = __cpu_to_le32((u32)dst); fifomm->Bdesc.Bcontrol = __cpu_to_le32(len & 0xffff); MDMA_MMFIFO_SOFT_RESET = __cpu_to_le32(1); MDMA_FIFOMM_SOFT_RESET = __cpu_to_le32(1); MDMA_MMFIFO_HEADPTR = __cpu_to_le32((u32)mmfifo); MDMA_MMFIFO_LOCK_TSFR_SIZE = __cpu_to_le32(64); MDMA_FIFOMM_HEADPTR = __cpu_to_le32((u32)fifomm); MDMA_FIFOMM_LOCK_TSFR_SIZE = __cpu_to_le32(64); MDMA_MMFIFO_START = __cpu_to_le32(0x1); MDMA_FIFOMM_START = __cpu_to_le32(0x1); while ((val = __le32_to_cpu(mmfifo->Fstatus)) == 0); while ((val = __le32_to_cpu(fifomm->Fstatus)) == 0); /* Return the CRC value */ *crc = __le32_to_cpu(fifomm->Fsystem); return 0; } #endif