static void ddr3_reset_data(u32 base, u32 ddr3_size) { u32 mpax[2]; u32 seg_num; u32 seg, blks, dst, edma_blks; struct edma3_slot_config slot; struct edma3_channel_config edma_channel; u32 edma_src[DDR3_EDMA_BLK_SIZE/4] __aligned(16) = {0, }; /* Setup an edma to copy the 1k block to the entire DDR */ puts("\nClear entire DDR3 memory to enable ECC\n"); /* save the SES MPAX regs */ if (cpu_is_k2g()) msmc_get_ses_mpax(K2G_MSMC_SEGMENT_ARM, 0, mpax); else msmc_get_ses_mpax(K2HKLE_MSMC_SEGMENT_ARM, 0, mpax); /* setup edma slot 1 configuration */ slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | EDMA3_SLOPT_COMP_CODE(0) | EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; slot.bcnt = DDR3_EDMA_BCNT; slot.acnt = DDR3_EDMA_BLK_SIZE; slot.ccnt = DDR3_EDMA_CCNT; slot.src_bidx = 0; slot.dst_bidx = DDR3_EDMA_BLK_SIZE; slot.src_cidx = 0; slot.dst_cidx = 0; slot.link = EDMA3_PARSET_NULL_LINK; slot.bcntrld = 0; edma3_slot_configure(KS2_EDMA0_BASE, DDR3_EDMA_SLOT_NUM, &slot); /* configure quik edma channel */ edma_channel.slot = DDR3_EDMA_SLOT_NUM; edma_channel.chnum = 0; edma_channel.complete_code = 0; /* event trigger after dst update */ edma_channel.trigger_slot_word = EDMA3_TWORD(dst); qedma3_start(KS2_EDMA0_BASE, &edma_channel); /* DDR3 size in segments (4KB seg size) */ seg_num = ddr3_size << (30 - KS2_MSMC_SEG_SIZE_SHIFT); for (seg = 0; seg < seg_num; seg += KS2_MSMC_MAP_SEG_NUM) { /* map 2GB 36-bit DDR address to 32-bit DDR address in EMIF access slave interface so that edma driver can access */ if (cpu_is_k2g()) { msmc_map_ses_segment(K2G_MSMC_SEGMENT_ARM, 0, base >> KS2_MSMC_SEG_SIZE_SHIFT, KS2_MSMC_DST_SEG_BASE + seg, MPAX_SEG_2G); } else { msmc_map_ses_segment(K2HKLE_MSMC_SEGMENT_ARM, 0, base >> KS2_MSMC_SEG_SIZE_SHIFT, KS2_MSMC_DST_SEG_BASE + seg, MPAX_SEG_2G); } if ((seg_num - seg) > KS2_MSMC_MAP_SEG_NUM) edma_blks = KS2_MSMC_MAP_SEG_NUM << (KS2_MSMC_SEG_SIZE_SHIFT - DDR3_EDMA_BLK_SIZE_SHIFT); else edma_blks = (seg_num - seg) << (KS2_MSMC_SEG_SIZE_SHIFT - DDR3_EDMA_BLK_SIZE_SHIFT); /* Use edma driver to scrub 2GB DDR memory */ for (dst = base, blks = 0; blks < edma_blks; blks += DDR3_EDMA_BCNT, dst += DDR3_EDMA_XF_SIZE) { edma3_set_src_addr(KS2_EDMA0_BASE, edma_channel.slot, (u32)edma_src); edma3_set_dest_addr(KS2_EDMA0_BASE, edma_channel.slot, (u32)dst); while (edma3_check_for_transfer(KS2_EDMA0_BASE, &edma_channel)) udelay(10); } }
void __edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num, void *dst, void *src, size_t len) { struct edma3_slot_config slot; struct edma3_channel_config edma_channel; int b_cnt_value = 1; int rem_bytes = 0; int a_cnt_value = len; unsigned int addr = (unsigned int) (dst); unsigned int max_acnt = 0x7FFFU; if (len > max_acnt) { b_cnt_value = (len / max_acnt); rem_bytes = (len % max_acnt); a_cnt_value = max_acnt; } slot.opt = 0; slot.src = ((unsigned int) src); slot.acnt = a_cnt_value; slot.bcnt = b_cnt_value; slot.ccnt = 1; slot.src_bidx = a_cnt_value; slot.dst_bidx = a_cnt_value; slot.src_cidx = 0; slot.dst_cidx = 0; slot.link = EDMA3_PARSET_NULL_LINK; slot.bcntrld = 0; slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | EDMA3_SLOPT_COMP_CODE(0) | EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; edma3_slot_configure(edma3_base_addr, edma_slot_num, &slot); edma_channel.slot = edma_slot_num; edma_channel.chnum = 0; edma_channel.complete_code = 0; /* set event trigger to dst update */ edma_channel.trigger_slot_word = EDMA3_TWORD(dst); qedma3_start(edma3_base_addr, &edma_channel); edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr); while (edma3_check_for_transfer(edma3_base_addr, &edma_channel)) ; qedma3_stop(edma3_base_addr, &edma_channel); if (rem_bytes != 0) { slot.opt = 0; slot.src = (b_cnt_value * max_acnt) + ((unsigned int) src); slot.acnt = rem_bytes; slot.bcnt = 1; slot.ccnt = 1; slot.src_bidx = rem_bytes; slot.dst_bidx = rem_bytes; slot.src_cidx = 0; slot.dst_cidx = 0; slot.link = EDMA3_PARSET_NULL_LINK; slot.bcntrld = 0; slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | EDMA3_SLOPT_COMP_CODE(0) | EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; edma3_slot_configure(edma3_base_addr, edma_slot_num, &slot); edma_channel.slot = edma_slot_num; edma_channel.chnum = 0; edma_channel.complete_code = 0; /* set event trigger to dst update */ edma_channel.trigger_slot_word = EDMA3_TWORD(dst); qedma3_start(edma3_base_addr, &edma_channel); edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr + (max_acnt * b_cnt_value)); while (edma3_check_for_transfer(edma3_base_addr, &edma_channel)) ; qedma3_stop(edma3_base_addr, &edma_channel); } }