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); } }
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); } }