/* Sets up SRC and DST CFG register for both logical and physical channels */
void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
		 u32 *src_cfg, u32 *dst_cfg, bool is_log)
{
	u32 src = 0;
	u32 dst = 0;

	if (!is_log) {
		/* Physical channel */
		if ((cfg->dir ==  STEDMA40_PERIPH_TO_MEM) ||
		    (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
			/* Set master port to 1 */
			src |= 1 << D40_SREG_CFG_MST_POS;
			src |= D40_TYPE_TO_EVENT(cfg->src_dev_type);

			if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
				src |= 1 << D40_SREG_CFG_PHY_TM_POS;
			else
				src |= 3 << D40_SREG_CFG_PHY_TM_POS;
		}
		if ((cfg->dir ==  STEDMA40_MEM_TO_PERIPH) ||
		    (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
			/* Set master port to 1 */
			dst |= 1 << D40_SREG_CFG_MST_POS;
			dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type);

			if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
				dst |= 1 << D40_SREG_CFG_PHY_TM_POS;
			else
				dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
		}
		/* Interrupt on end of transfer for destination */
		dst |= 1 << D40_SREG_CFG_TIM_POS;

		/* Generate interrupt on error */
		src |= 1 << D40_SREG_CFG_EIM_POS;
		dst |= 1 << D40_SREG_CFG_EIM_POS;

		/* PSIZE */
		if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
			src |= 1 << D40_SREG_CFG_PHY_PEN_POS;
			src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
		}
		if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
			dst |= 1 << D40_SREG_CFG_PHY_PEN_POS;
			dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
		}

		/* Element size */
		src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS;
		dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS;

	} else {
		/* Logical channel */
		dst |= 1 << D40_SREG_CFG_LOG_GIM_POS;
		src |= 1 << D40_SREG_CFG_LOG_GIM_POS;
	}

	if (cfg->channel_type & STEDMA40_HIGH_PRIORITY_CHANNEL) {
		src |= 1 << D40_SREG_CFG_PRI_POS;
		dst |= 1 << D40_SREG_CFG_PRI_POS;
	}

	src |= cfg->src_info.endianess << D40_SREG_CFG_LBE_POS;
	dst |= cfg->dst_info.endianess << D40_SREG_CFG_LBE_POS;

	*src_cfg = src;
	*dst_cfg = dst;
}
Beispiel #2
0
void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg)
{
    u32 src = 0;
    u32 dst = 0;

    if ((cfg->dir == DMA_DEV_TO_MEM) ||
            (cfg->dir == DMA_DEV_TO_DEV)) {
        /* Set master port to 1 */
        src |= BIT(D40_SREG_CFG_MST_POS);
        src |= D40_TYPE_TO_EVENT(cfg->dev_type);

        if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
            src |= BIT(D40_SREG_CFG_PHY_TM_POS);
        else
            src |= 3 << D40_SREG_CFG_PHY_TM_POS;
    }
    if ((cfg->dir == DMA_MEM_TO_DEV) ||
            (cfg->dir == DMA_DEV_TO_DEV)) {
        /* Set master port to 1 */
        dst |= BIT(D40_SREG_CFG_MST_POS);
        dst |= D40_TYPE_TO_EVENT(cfg->dev_type);

        if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
            dst |= BIT(D40_SREG_CFG_PHY_TM_POS);
        else
            dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
    }
    /* Interrupt on end of transfer for destination */
    dst |= BIT(D40_SREG_CFG_TIM_POS);

    /* Generate interrupt on error */
    src |= BIT(D40_SREG_CFG_EIM_POS);
    dst |= BIT(D40_SREG_CFG_EIM_POS);

    /* PSIZE */
    if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
        src |= BIT(D40_SREG_CFG_PHY_PEN_POS);
        src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
    }
    if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
        dst |= BIT(D40_SREG_CFG_PHY_PEN_POS);
        dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
    }

    /* Element size */
    src |= d40_width_to_bits(cfg->src_info.data_width)
           << D40_SREG_CFG_ESIZE_POS;
    dst |= d40_width_to_bits(cfg->dst_info.data_width)
           << D40_SREG_CFG_ESIZE_POS;

    /* Set the priority bit to high for the physical channel */
    if (cfg->high_priority) {
        src |= BIT(D40_SREG_CFG_PRI_POS);
        dst |= BIT(D40_SREG_CFG_PRI_POS);
    }

    if (cfg->src_info.big_endian)
        src |= BIT(D40_SREG_CFG_LBE_POS);
    if (cfg->dst_info.big_endian)
        dst |= BIT(D40_SREG_CFG_LBE_POS);

    *src_cfg = src;
    *dst_cfg = dst;
}