static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode) { struct drm_device *dev = crtc->dev; struct amdgpu_device *adev = dev->dev_private; struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); unsigned type; if (amdgpu_sriov_vf(adev)) return; switch (mode) { case DRM_MODE_DPMS_ON: amdgpu_crtc->enabled = true; /* Make sure VBLANK interrupts are still enabled */ type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); drm_crtc_vblank_on(crtc); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: drm_crtc_vblank_off(crtc); amdgpu_crtc->enabled = false; break; } }
static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) { struct drm_crtc *crtc = &rcrtc->crtc; bool interlaced; if (rcrtc->started) return; /* Set display off and background to black */ rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0)); rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0)); /* Configure display timings and output routing */ rcar_du_crtc_set_display_timing(rcrtc); rcar_du_group_set_routing(rcrtc->group); /* Start with all planes disabled. */ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0); /* Select master sync mode. This enables display operation in master * sync mode (with the HSYNC and VSYNC signals configured as outputs and * actively driven). */ interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE; rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK, (interlaced ? DSYSR_SCM_INT_VIDEO : 0) | DSYSR_TVM_MASTER); rcar_du_group_start_stop(rcrtc->group, true); /* Turn vertical blanking interrupt reporting back on. */ drm_crtc_vblank_on(crtc); rcrtc->started = true; }
static void hdlcd_crtc_enable(struct drm_crtc *crtc) { struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); clk_prepare_enable(hdlcd->clk); hdlcd_crtc_mode_set_nofb(crtc); hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); drm_crtc_vblank_on(crtc); }
static void exynos_drm_crtc_enable(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); if (exynos_crtc->ops->enable) exynos_crtc->ops->enable(exynos_crtc); drm_crtc_vblank_on(crtc); }
static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; clk_prepare_enable(fsl_dev->pix_clk); regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, DCU_MODE_DCU_MODE_MASK, DCU_MODE_DCU_MODE(DCU_MODE_NORMAL)); regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG); drm_crtc_vblank_on(crtc); }
static void omap_crtc_enable(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); DBG("%s", omap_crtc->name); rmb(); WARN_ON(omap_crtc->pending); omap_crtc->pending = true; wmb(); omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); drm_crtc_vblank_on(crtc); }
static void ipu_fb_enable(struct ipu_crtc *ipu_crtc) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); if (ipu_crtc->enabled) return; ipu_dc_enable(ipu); ipu_plane_enable(ipu_crtc->plane[0]); /* Start DC channel and DI after IDMAC */ ipu_dc_enable_channel(ipu_crtc->dc); ipu_di_enable(ipu_crtc->di); drm_crtc_vblank_on(&ipu_crtc->base); ipu_crtc->enabled = 1; }
static void ade_crtc_enable(struct drm_crtc *crtc) { struct ade_crtc *acrtc = to_ade_crtc(crtc); struct ade_hw_ctx *ctx = acrtc->ctx; int ret; if (acrtc->enable) return; if (!ctx->power_on) { ret = ade_power_up(ctx); if (ret) return; } ade_set_medianoc_qos(acrtc); ade_display_enable(acrtc); ade_dump_regs(ctx->base); drm_crtc_vblank_on(crtc); acrtc->enable = true; }
static void pl111_display_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *cstate, struct drm_plane_state *plane_state) { struct drm_crtc *crtc = &pipe->crtc; struct drm_plane *plane = &pipe->plane; struct drm_device *drm = crtc->dev; struct pl111_drm_dev_private *priv = drm->dev_private; const struct drm_display_mode *mode = &cstate->mode; struct drm_framebuffer *fb = plane->state->fb; struct drm_connector *connector = priv->connector; struct drm_bridge *bridge = priv->bridge; u32 cntl; u32 ppl, hsw, hfp, hbp; u32 lpp, vsw, vfp, vbp; u32 cpl, tim2; int ret; ret = clk_set_rate(priv->clk, mode->clock * 1000); if (ret) { dev_err(drm->dev, "Failed to set pixel clock rate to %d: %d\n", mode->clock * 1000, ret); } clk_prepare_enable(priv->clk); ppl = (mode->hdisplay / 16) - 1; hsw = mode->hsync_end - mode->hsync_start - 1; hfp = mode->hsync_start - mode->hdisplay - 1; hbp = mode->htotal - mode->hsync_end - 1; lpp = mode->vdisplay - 1; vsw = mode->vsync_end - mode->vsync_start - 1; vfp = mode->vsync_start - mode->vdisplay; vbp = mode->vtotal - mode->vsync_end; cpl = mode->hdisplay - 1; writel((ppl << 2) | (hsw << 8) | (hfp << 16) | (hbp << 24), priv->regs + CLCD_TIM0); writel(lpp | (vsw << 10) | (vfp << 16) | (vbp << 24), priv->regs + CLCD_TIM1); spin_lock(&priv->tim2_lock); tim2 = readl(priv->regs + CLCD_TIM2); tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); if (priv->variant->broken_clockdivider) tim2 |= TIM2_BCD; if (mode->flags & DRM_MODE_FLAG_NHSYNC) tim2 |= TIM2_IHS; if (mode->flags & DRM_MODE_FLAG_NVSYNC) tim2 |= TIM2_IVS; if (connector) { if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) tim2 |= TIM2_IOE; if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE) tim2 |= TIM2_IPC; } if (bridge) { const struct drm_bridge_timings *btimings = bridge->timings; /* * Here is when things get really fun. Sometimes the bridge * timings are such that the signal out from PL11x is not * stable before the receiving bridge (such as a dumb VGA DAC * or similar) samples it. If that happens, we compensate by * the only method we have: output the data on the opposite * edge of the clock so it is for sure stable when it gets * sampled. * * The PL111 manual does not contain proper timining diagrams * or data for these details, but we know from experiments * that the setup time is more than 3000 picoseconds (3 ns). * If we have a bridge that requires the signal to be stable * earlier than 3000 ps before the clock pulse, we have to * output the data on the opposite edge to avoid flicker. */ if (btimings && btimings->setup_time_ps >= 3000) tim2 ^= TIM2_IPC; } tim2 |= cpl << 16; writel(tim2, priv->regs + CLCD_TIM2); spin_unlock(&priv->tim2_lock); writel(0, priv->regs + CLCD_TIM3); /* Hard-code TFT panel */ cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); /* Note that the the hardware's format reader takes 'r' from * the low bit, while DRM formats list channels from high bit * to low bit as you read left to right. */ switch (fb->format->format) { case DRM_FORMAT_ABGR8888: case DRM_FORMAT_XBGR8888: cntl |= CNTL_LCDBPP24; break; case DRM_FORMAT_ARGB8888: case DRM_FORMAT_XRGB8888: cntl |= CNTL_LCDBPP24 | CNTL_BGR; break; case DRM_FORMAT_BGR565: if (priv->variant->is_pl110) cntl |= CNTL_LCDBPP16; else cntl |= CNTL_LCDBPP16_565; break; case DRM_FORMAT_RGB565: if (priv->variant->is_pl110) cntl |= CNTL_LCDBPP16; else cntl |= CNTL_LCDBPP16_565; cntl |= CNTL_BGR; break; case DRM_FORMAT_ABGR1555: case DRM_FORMAT_XBGR1555: cntl |= CNTL_LCDBPP16; break; case DRM_FORMAT_ARGB1555: case DRM_FORMAT_XRGB1555: cntl |= CNTL_LCDBPP16 | CNTL_BGR; break; case DRM_FORMAT_ABGR4444: case DRM_FORMAT_XBGR4444: cntl |= CNTL_LCDBPP16_444; break; case DRM_FORMAT_ARGB4444: case DRM_FORMAT_XRGB4444: cntl |= CNTL_LCDBPP16_444 | CNTL_BGR; break; default: WARN_ONCE(true, "Unknown FB format 0x%08x\n", fb->format->format); break; } /* The PL110 in Integrator/Versatile does the BGR routing externally */ if (priv->variant->external_bgr) cntl &= ~CNTL_BGR; /* Power sequence: first enable and chill */ writel(cntl, priv->regs + priv->ctrl); /* * We expect this delay to stabilize the contrast * voltage Vee as stipulated by the manual */ msleep(20); if (priv->variant_display_enable) priv->variant_display_enable(drm, fb->format->format); /* Power Up */ cntl |= CNTL_LCDPWR; writel(cntl, priv->regs + priv->ctrl); if (!priv->variant->broken_vblank) drm_crtc_vblank_on(crtc); }