static void sun4i_crtc_enable(struct drm_crtc *crtc) { struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct sun4i_drv *drv = scrtc->drv; DRM_DEBUG_DRIVER("Enabling the CRTC\n"); sun4i_tcon_enable(drv->tcon); }
static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); struct sun4i_tcon *tcon = crtc->tcon; unsigned int x, y; u32 val; sun4i_tcon1_mode_set(tcon, mode); sun4i_tcon_set_mux(tcon, 1, encoder); clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000); clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000); /* Set input sync enable */ writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC, hdmi->base + SUN4I_HDMI_UNKNOWN_REG); /* Setup timing registers */ writel(SUN4I_HDMI_VID_TIMING_X(mode->hdisplay) | SUN4I_HDMI_VID_TIMING_Y(mode->vdisplay), hdmi->base + SUN4I_HDMI_VID_TIMING_ACT_REG); x = mode->htotal - mode->hsync_start; y = mode->vtotal - mode->vsync_start; writel(SUN4I_HDMI_VID_TIMING_X(x) | SUN4I_HDMI_VID_TIMING_Y(y), hdmi->base + SUN4I_HDMI_VID_TIMING_BP_REG); x = mode->hsync_start - mode->hdisplay; y = mode->vsync_start - mode->vdisplay; writel(SUN4I_HDMI_VID_TIMING_X(x) | SUN4I_HDMI_VID_TIMING_Y(y), hdmi->base + SUN4I_HDMI_VID_TIMING_FP_REG); x = mode->hsync_end - mode->hsync_start; y = mode->vsync_end - mode->vsync_start; writel(SUN4I_HDMI_VID_TIMING_X(x) | SUN4I_HDMI_VID_TIMING_Y(y), hdmi->base + SUN4I_HDMI_VID_TIMING_SPW_REG); val = SUN4I_HDMI_VID_TIMING_POL_TX_CLK; if (mode->flags & DRM_MODE_FLAG_PHSYNC) val |= SUN4I_HDMI_VID_TIMING_POL_HSYNC; if (mode->flags & DRM_MODE_FLAG_PVSYNC) val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC; writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); }
static void sun4i_hdmi_disable(struct drm_encoder *encoder) { struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); struct sun4i_tcon *tcon = crtc->tcon; u32 val; DRM_DEBUG_DRIVER("Disabling the HDMI Output\n"); val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG); val &= ~SUN4I_HDMI_VID_CTRL_ENABLE; writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); sun4i_tcon_channel_disable(tcon, 1); }
static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct drm_device *dev = crtc->dev; unsigned long flags; if (crtc->state->event) { WARN_ON(drm_crtc_vblank_get(crtc) != 0); spin_lock_irqsave(&dev->event_lock, flags); scrtc->event = crtc->state->event; spin_unlock_irqrestore(&dev->event_lock, flags); crtc->state->event = NULL; } }
static void sun4i_crtc_disable(struct drm_crtc *crtc) { struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct sun4i_drv *drv = scrtc->drv; DRM_DEBUG_DRIVER("Disabling the CRTC\n"); sun4i_tcon_disable(drv->tcon); if (crtc->state->event && !crtc->state->active) { spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event); spin_unlock_irq(&crtc->dev->event_lock); crtc->state->event = NULL; } }
static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct sun4i_drv *drv = scrtc->drv; struct drm_pending_vblank_event *event = crtc->state->event; DRM_DEBUG_DRIVER("Committing plane changes\n"); sun4i_backend_commit(drv->backend); if (event) { crtc->state->event = NULL; spin_lock_irq(&crtc->dev->event_lock); if (drm_crtc_vblank_get(crtc) == 0) drm_crtc_arm_vblank_event(crtc, event); else drm_crtc_send_vblank_event(crtc, event); spin_unlock_irq(&crtc->dev->event_lock); } }
static void sun4i_hdmi_enable(struct drm_encoder *encoder) { struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); struct sun4i_tcon *tcon = crtc->tcon; u32 val = 0; DRM_DEBUG_DRIVER("Enabling the HDMI Output\n"); sun4i_tcon_channel_enable(tcon, 1); sun4i_hdmi_setup_avi_infoframes(hdmi, mode); val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0)); val = SUN4I_HDMI_VID_CTRL_ENABLE; if (hdmi->hdmi_monitor) val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); }