Ejemplo n.º 1
0
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);
		}
	}
Ejemplo n.º 2
0
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);
    }
}