Ejemplo n.º 1
0
void sc_hwset_pre_multi_format(struct sc_dev *sc, bool src, bool dst)
{
	unsigned long cfg = readl(sc->regs + SCALER_SRC_CFG);

	if (sc->version == SCALER_VERSION(4, 0, 1)) {
		if (src != dst)
			dev_err(sc->dev,
			"pre-multi fmt should be same between src and dst\n");
		return;
	}

	if (src && ((cfg & SCALER_CFG_FMT_MASK) == SCALER_CFG_FMT_ARGB8888)) {
		cfg &= ~SCALER_CFG_FMT_MASK;
		cfg |= SCALER_CFG_FMT_P_ARGB8888;
		writel(cfg, sc->regs + SCALER_SRC_CFG);
	}

	cfg = readl(sc->regs + SCALER_DST_CFG);
	if (dst && ((cfg & SCALER_CFG_FMT_MASK) == SCALER_CFG_FMT_ARGB8888)) {
		cfg &= ~SCALER_CFG_FMT_MASK;
		cfg |= SCALER_CFG_FMT_P_ARGB8888;
		writel(cfg, sc->regs + SCALER_DST_CFG);
	}
}
Ejemplo n.º 2
0
void sc_hwset_blend(struct sc_dev *sc, enum sc_blend_op bl_op, bool pre_multi,
		unsigned char g_alpha, struct sc_src_blend_cfg *src_blend_cfg)
{
	unsigned int cfg = __raw_readl(sc->regs + SCALER_CFG);
	int idx = bl_op - 1;

	cfg |= SCALER_CFG_BLEND_EN;
	__raw_writel(cfg, sc->regs + SCALER_CFG);

	cfg = __raw_readl(sc->regs + SCALER_SRC_BLEND_COLOR);
	get_blend_value(&cfg, sc_bl_op_tbl[idx].src_color, pre_multi);
	if (g_alpha < 0xff)
		cfg |= (SRC_GA << SCALER_OP_SEL_SHIFT);
	__raw_writel(cfg, sc->regs + SCALER_SRC_BLEND_COLOR);
	sc_dbg("src_blend_color is 0x%x, %d\n", cfg, pre_multi);

	cfg = __raw_readl(sc->regs + SCALER_SRC_BLEND_ALPHA);
	get_blend_value(&cfg, sc_bl_op_tbl[idx].src_alpha, 1);
	if (g_alpha < 0xff)
		cfg |= (SRC_GA << SCALER_OP_SEL_SHIFT) | (g_alpha << 0);
	__raw_writel(cfg, sc->regs + SCALER_SRC_BLEND_ALPHA);
	sc_dbg("src_blend_alpha is 0x%x\n", cfg);

	cfg = __raw_readl(sc->regs + SCALER_DST_BLEND_COLOR);
	get_blend_value(&cfg, sc_bl_op_tbl[idx].dst_color, pre_multi);
	if (g_alpha < 0xff)
		cfg |= ((INV_SAGA & 0xf) << SCALER_OP_SEL_SHIFT);
	__raw_writel(cfg, sc->regs + SCALER_DST_BLEND_COLOR);
	sc_dbg("dst_blend_color is 0x%x\n", cfg);

	cfg = __raw_readl(sc->regs + SCALER_DST_BLEND_ALPHA);
	get_blend_value(&cfg, sc_bl_op_tbl[idx].dst_alpha, 1);
	if (g_alpha < 0xff)
		cfg |= ((INV_SAGA & 0xf) << SCALER_OP_SEL_SHIFT);
	__raw_writel(cfg, sc->regs + SCALER_DST_BLEND_ALPHA);
	sc_dbg("dst_blend_alpha is 0x%x\n", cfg);

	/*
	 * If dst format is non-premultiplied format
	 * and blending operation is enabled,
	 * result image should be divided by alpha value
	 * because the result is always pre-multiplied.
	 */
	if (!pre_multi && sc->version != SCALER_VERSION(2, 2, 0)) {
		cfg = readl(sc->regs + SCALER_CFG);
		cfg |= SCALER_CFG_BL_DIV_ALPHA_EN;
		__raw_writel(cfg, sc->regs + SCALER_CFG);
	}

	/* Set source blending configuration */
	if (sc->version == SCALER_VERSION(2, 2, 0)) {
		sc_set_blendsrc_cfg(sc, pre_multi, src_blend_cfg);

		/* span in the units of pixels */
		sc_set_blend_src_span(sc, src_blend_cfg->blend_src_stride);

		sc_blend_src_pos(sc,
				src_blend_cfg->blend_src_h_pos,
				src_blend_cfg->blend_src_v_pos);
		sc_blend_src_wh(sc,
				src_blend_cfg->blend_src_crop_width,
				src_blend_cfg->blend_src_crop_height);
	}
}