drm/amdgpu: Initialize dce_virtual_crtc_helper_funcs
authorEmily Deng <Emily.Deng@amd.com>
Mon, 8 Aug 2016 03:32:00 +0000 (11:32 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Aug 2016 17:57:04 +0000 (13:57 -0400)
For virtual display feature, initialize dce_virtual_crtc_helper_funcs.

Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/dce_virtual.c

index 985b276e6b2504b1d6066f6a73e46cd773e0581a..11f04ec51c9c7bd59e70d1adc37500d114b03d28 100644 (file)
@@ -134,16 +134,135 @@ static const struct drm_crtc_funcs dce_virtual_crtc_funcs = {
        .page_flip = NULL,
 };
 
+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;
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               amdgpu_crtc->enabled = true;
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
+               type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
+               amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
+               drm_vblank_on(dev, amdgpu_crtc->crtc_id);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               drm_vblank_off(dev, amdgpu_crtc->crtc_id);
+               amdgpu_crtc->enabled = false;
+               break;
+       }
+}
+
+
+static void dce_virtual_crtc_prepare(struct drm_crtc *crtc)
+{
+       dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void dce_virtual_crtc_commit(struct drm_crtc *crtc)
+{
+       dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
+{
+       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+
+       dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+       if (crtc->primary->fb) {
+               int r;
+               struct amdgpu_framebuffer *amdgpu_fb;
+               struct amdgpu_bo *rbo;
+
+               amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
+               rbo = gem_to_amdgpu_bo(amdgpu_fb->obj);
+               r = amdgpu_bo_reserve(rbo, false);
+               if (unlikely(r))
+                       DRM_ERROR("failed to reserve rbo before unpin\n");
+               else {
+                       amdgpu_bo_unpin(rbo);
+                       amdgpu_bo_unreserve(rbo);
+               }
+       }
+
+       amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
+       amdgpu_crtc->encoder = NULL;
+       amdgpu_crtc->connector = NULL;
+}
+
+static int dce_virtual_crtc_mode_set(struct drm_crtc *crtc,
+                                 struct drm_display_mode *mode,
+                                 struct drm_display_mode *adjusted_mode,
+                                 int x, int y, struct drm_framebuffer *old_fb)
+{
+       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+
+       /* update the hw version fpr dpm */
+       amdgpu_crtc->hw_mode = *adjusted_mode;
+
+       return 0;
+}
+
+static bool dce_virtual_crtc_mode_fixup(struct drm_crtc *crtc,
+                                    const struct drm_display_mode *mode,
+                                    struct drm_display_mode *adjusted_mode)
+{
+       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct drm_encoder *encoder;
+
+       /* assign the encoder to the amdgpu crtc to avoid repeated lookups later */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->crtc == crtc) {
+                       amdgpu_crtc->encoder = encoder;
+                       amdgpu_crtc->connector = amdgpu_get_connector_for_encoder(encoder);
+                       break;
+               }
+       }
+       if ((amdgpu_crtc->encoder == NULL) || (amdgpu_crtc->connector == NULL)) {
+               amdgpu_crtc->encoder = NULL;
+               amdgpu_crtc->connector = NULL;
+               return false;
+       }
+
+       return true;
+}
+
+
+static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
+                                 struct drm_framebuffer *old_fb)
+{
+       return 0;
+}
+
+static void dce_virtual_crtc_load_lut(struct drm_crtc *crtc)
+{
+       return;
+}
+
+static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
+                                        struct drm_framebuffer *fb,
+                                        int x, int y, enum mode_set_atomic state)
+{
+       return 0;
+}
+
 static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
-       .dpms = NULL,
-       .mode_fixup = NULL,
-       .mode_set = NULL,
-       .mode_set_base = NULL,
-       .mode_set_base_atomic = NULL,
-       .prepare = NULL,
-       .commit = NULL,
-       .load_lut = NULL,
-       .disable = NULL,
+       .dpms = dce_virtual_crtc_dpms,
+       .mode_fixup = dce_virtual_crtc_mode_fixup,
+       .mode_set = dce_virtual_crtc_mode_set,
+       .mode_set_base = dce_virtual_crtc_set_base,
+       .mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
+       .prepare = dce_virtual_crtc_prepare,
+       .commit = dce_virtual_crtc_commit,
+       .load_lut = dce_virtual_crtc_load_lut,
+       .disable = dce_virtual_crtc_disable,
 };
 
 static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)