void sc_hwset_blend(struct sc_dev *sc, enum sc_blend_op bl_op, bool pre_multi,
		unsigned char g_alpha)
{
	unsigned int cfg = readl(sc->regs + SCALER_CFG);
	int idx = bl_op - 1;

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

	cfg = 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);
	writel(cfg, sc->regs + SCALER_SRC_BLEND_COLOR);
	sc_dbg("src_blend_color is 0x%x, %d\n", cfg, pre_multi);

	cfg = 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);
	writel(cfg, sc->regs + SCALER_SRC_BLEND_ALPHA);
	sc_dbg("src_blend_alpha is 0x%x\n", cfg);

	cfg = 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);
	writel(cfg, sc->regs + SCALER_DST_BLEND_COLOR);
	sc_dbg("dst_blend_color is 0x%x\n", cfg);

	cfg = 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);
	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) {
		cfg = readl(sc->regs + SCALER_CFG);
		cfg |= SCALER_CFG_BL_DIV_ALPHA_EN;
		writel(cfg, sc->regs + SCALER_CFG);
	}
}
Exemple #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);
	}
}