Exemple #1
0
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;
	}
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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);
}