static void ade_compositor_routing_disable(void __iomem *base, u32 ch) { u8 ovly_ch = 0; /* TODO: Only primary plane now */ /* disable this plane/channel */ ade_update_bits(base + ADE_OVLY_CH_CTL(ovly_ch), CH_EN_OFST, MASK(1), 0); /* dis-connect this plane/channel of overlay2 compositor */ ade_update_bits(base + ADE_OVLY_CTL, CH_OVLY_SEL_OFST(ovly_ch), CH_OVLY_SEL_MASK, 0); }
static void ade_compositor_routing_set(void __iomem *base, u8 ch, u32 x0, u32 y0, u32 in_w, u32 in_h, u32 fmt) { u8 ovly_ch = 0; /* TODO: This is the zpos, only one plane now */ u8 glb_alpha = 255; u32 x1 = x0 + in_w - 1; u32 y1 = y0 + in_h - 1; u32 val; u8 alp_sel; u8 under_alp_sel; u8 alp_mode; ade_get_blending_params(fmt, glb_alpha, &alp_mode, &alp_sel, &under_alp_sel); /* overlay routing setting */ writel(x0 << 16 | y0, base + ADE_OVLY_CH_XY0(ovly_ch)); writel(x1 << 16 | y1, base + ADE_OVLY_CH_XY1(ovly_ch)); val = (ch + 1) << CH_SEL_OFST | BIT(CH_EN_OFST) | alp_sel << CH_ALP_SEL_OFST | under_alp_sel << CH_UNDER_ALP_SEL_OFST | glb_alpha << CH_ALP_GBL_OFST | alp_mode << CH_ALP_MODE_OFST; writel(val, base + ADE_OVLY_CH_CTL(ovly_ch)); /* connect this plane/channel to overlay2 compositor */ ade_update_bits(base + ADE_OVLY_CTL, CH_OVLY_SEL_OFST(ovly_ch), CH_OVLY_SEL_MASK, CH_OVLY_SEL_VAL(OUT_OVLY)); }
static void ade_update_reload_bit(void __iomem *base, u32 bit_num, u32 val) { u32 bit_ofst, reg_num; bit_ofst = bit_num % 32; reg_num = bit_num / 32; ade_update_bits(base + ADE_RELOAD_DIS(reg_num), bit_ofst, MASK(1), !!val); }
static void ade_init(struct ade_hw_ctx *ctx) { void __iomem *base = ctx->base; /* enable clk gate */ ade_update_bits(base + ADE_CTRL1, AUTO_CLK_GATE_EN_OFST, AUTO_CLK_GATE_EN, ADE_ENABLE); /* clear overlay */ writel(0, base + ADE_OVLY1_TRANS_CFG); writel(0, base + ADE_OVLY_CTL); writel(0, base + ADE_OVLYX_CTL(OUT_OVLY)); /* clear reset and reload regs */ writel(MASK(32), base + ADE_SOFT_RST_SEL(0)); writel(MASK(32), base + ADE_SOFT_RST_SEL(1)); writel(MASK(32), base + ADE_RELOAD_DIS(0)); writel(MASK(32), base + ADE_RELOAD_DIS(1)); /* * for video mode, all the ade registers should * become effective at frame end. */ ade_update_bits(base + ADE_CTRL, FRM_END_START_OFST, FRM_END_START_MASK, REG_EFFECTIVE_IN_ADEEN_FRMEND); }
static void ade_crtc_disable_vblank(struct drm_crtc *crtc) { struct ade_crtc *acrtc = to_ade_crtc(crtc); struct ade_hw_ctx *ctx = acrtc->ctx; void __iomem *base = ctx->base; if (!ctx->power_on) { DRM_ERROR("power is down! vblank disable fail\n"); return; } ade_update_bits(base + LDI_INT_EN, FRAME_END_INT_EN_OFST, MASK(1), 0); }
static int ade_crtc_enable_vblank(struct drm_crtc *crtc) { struct ade_crtc *acrtc = to_ade_crtc(crtc); struct ade_hw_ctx *ctx = acrtc->ctx; void __iomem *base = ctx->base; if (!ctx->power_on) (void)ade_power_up(ctx); ade_update_bits(base + LDI_INT_EN, FRAME_END_INT_EN_OFST, MASK(1), 1); return 0; }
static void ade_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct kirin_drm_private *priv = dev->dev_private; struct ade_crtc *acrtc = to_ade_crtc(priv->crtc[pipe]); struct ade_hw_ctx *ctx = acrtc->ctx; void __iomem *base = ctx->base; if (!ctx->power_on) { DRM_ERROR("power is down! vblank disable fail\n"); return; } ade_update_bits(base + LDI_INT_EN, FRAME_END_INT_EN_OFST, MASK(1), 0); }
static int ade_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct kirin_drm_private *priv = dev->dev_private; struct ade_crtc *acrtc = to_ade_crtc(priv->crtc[pipe]); struct ade_hw_ctx *ctx = acrtc->ctx; void __iomem *base = ctx->base; if (!ctx->power_on) (void)ade_power_up(ctx); ade_update_bits(base + LDI_INT_EN, FRAME_END_INT_EN_OFST, MASK(1), 1); return 0; }
static irqreturn_t ade_irq_handler(int irq, void *data) { struct ade_crtc *acrtc = data; struct ade_hw_ctx *ctx = acrtc->ctx; struct drm_crtc *crtc = &acrtc->base; void __iomem *base = ctx->base; u32 status; status = readl(base + LDI_MSK_INT); DRM_DEBUG_VBL("LDI IRQ: status=0x%X\n", status); /* vblank irq */ if (status & BIT(FRAME_END_INT_EN_OFST)) { ade_update_bits(base + LDI_INT_CLR, FRAME_END_INT_EN_OFST, MASK(1), 1); drm_crtc_handle_vblank(crtc); } return IRQ_HANDLED; }