Merge tag 'drm-intel-next-2018-02-21' of git://anongit.freedesktop.org/drm/drm-intel...
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_display.c
index c2fa5d55f04e992a4daad13515ced5f495bdd9ce..93f700ab1bfbfbd75b29757d9acbff329e88e898 100644 (file)
@@ -29,6 +29,7 @@
 #include "amdgpu_i2c.h"
 #include "atom.h"
 #include "amdgpu_connectors.h"
+#include "amdgpu_display.h"
 #include <asm/div64.h>
 
 #include <linux/pm_runtime.h>
@@ -36,7 +37,8 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_fb_helper.h>
 
-static void amdgpu_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb)
+static void amdgpu_display_flip_callback(struct dma_fence *f,
+                                        struct dma_fence_cb *cb)
 {
        struct amdgpu_flip_work *work =
                container_of(cb, struct amdgpu_flip_work, cb);
@@ -45,8 +47,8 @@ static void amdgpu_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb)
        schedule_work(&work->flip_work.work);
 }
 
-static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
-                                    struct dma_fence **f)
+static bool amdgpu_display_flip_handle_fence(struct amdgpu_flip_work *work,
+                                            struct dma_fence **f)
 {
        struct dma_fence *fence= *f;
 
@@ -55,14 +57,15 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
 
        *f = NULL;
 
-       if (!dma_fence_add_callback(fence, &work->cb, amdgpu_flip_callback))
+       if (!dma_fence_add_callback(fence, &work->cb,
+                                   amdgpu_display_flip_callback))
                return true;
 
        dma_fence_put(fence);
        return false;
 }
 
-static void amdgpu_flip_work_func(struct work_struct *__work)
+static void amdgpu_display_flip_work_func(struct work_struct *__work)
 {
        struct delayed_work *delayed_work =
                container_of(__work, struct delayed_work, work);
@@ -76,20 +79,20 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
        unsigned i;
        int vpos, hpos;
 
-       if (amdgpu_flip_handle_fence(work, &work->excl))
+       if (amdgpu_display_flip_handle_fence(work, &work->excl))
                return;
 
        for (i = 0; i < work->shared_count; ++i)
-               if (amdgpu_flip_handle_fence(work, &work->shared[i]))
+               if (amdgpu_display_flip_handle_fence(work, &work->shared[i]))
                        return;
 
        /* Wait until we're out of the vertical blank period before the one
         * targeted by the flip
         */
        if (amdgpu_crtc->enabled &&
-           (amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 0,
-                                       &vpos, &hpos, NULL, NULL,
-                                       &crtc->hwmode)
+           (amdgpu_display_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 0,
+                                               &vpos, &hpos, NULL, NULL,
+                                               &crtc->hwmode)
             & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
            (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
            (int)(work->target_vblank -
@@ -117,7 +120,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
 /*
  * Handle unpin events outside the interrupt handler proper.
  */
-static void amdgpu_unpin_work_func(struct work_struct *__work)
+static void amdgpu_display_unpin_work_func(struct work_struct *__work)
 {
        struct amdgpu_flip_work *work =
                container_of(__work, struct amdgpu_flip_work, unpin_work);
@@ -139,11 +142,11 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
        kfree(work);
 }
 
-int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
-                                struct drm_framebuffer *fb,
-                                struct drm_pending_vblank_event *event,
-                                uint32_t page_flip_flags, uint32_t target,
-                                struct drm_modeset_acquire_ctx *ctx)
+int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
+                               struct drm_framebuffer *fb,
+                               struct drm_pending_vblank_event *event,
+                               uint32_t page_flip_flags, uint32_t target,
+                               struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_device *dev = crtc->dev;
        struct amdgpu_device *adev = dev->dev_private;
@@ -162,8 +165,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
        if (work == NULL)
                return -ENOMEM;
 
-       INIT_DELAYED_WORK(&work->flip_work, amdgpu_flip_work_func);
-       INIT_WORK(&work->unpin_work, amdgpu_unpin_work_func);
+       INIT_DELAYED_WORK(&work->flip_work, amdgpu_display_flip_work_func);
+       INIT_WORK(&work->unpin_work, amdgpu_display_unpin_work_func);
 
        work->event = event;
        work->adev = adev;
@@ -189,7 +192,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
                goto cleanup;
        }
 
-       r = amdgpu_bo_pin(new_abo, AMDGPU_GEM_DOMAIN_VRAM, &base);
+       r = amdgpu_bo_pin(new_abo, amdgpu_display_framebuffer_domains(adev), &base);
        if (unlikely(r != 0)) {
                DRM_ERROR("failed to pin new abo buffer before flip\n");
                goto unreserve;
@@ -228,7 +231,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
        /* update crtc fb */
        crtc->primary->fb = fb;
        spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-       amdgpu_flip_work_func(&work->flip_work.work);
+       amdgpu_display_flip_work_func(&work->flip_work.work);
        return 0;
 
 pflip_cleanup:
@@ -254,8 +257,8 @@ cleanup:
        return r;
 }
 
-int amdgpu_crtc_set_config(struct drm_mode_set *set,
-                          struct drm_modeset_acquire_ctx *ctx)
+int amdgpu_display_crtc_set_config(struct drm_mode_set *set,
+                                  struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_device *dev;
        struct amdgpu_device *adev;
@@ -352,7 +355,7 @@ static const char *hpd_names[6] = {
        "HPD6",
 };
 
-void amdgpu_print_display_setup(struct drm_device *dev)
+void amdgpu_display_print_display_setup(struct drm_device *dev)
 {
        struct drm_connector *connector;
        struct amdgpu_connector *amdgpu_connector;
@@ -429,11 +432,11 @@ void amdgpu_print_display_setup(struct drm_device *dev)
 }
 
 /**
- * amdgpu_ddc_probe
+ * amdgpu_display_ddc_probe
  *
  */
-bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector,
-                      bool use_aux)
+bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector,
+                             bool use_aux)
 {
        u8 out = 0x0;
        u8 buf[8];
@@ -479,7 +482,7 @@ bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector,
        return true;
 }
 
-static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
+static void amdgpu_display_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
        struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
 
@@ -488,9 +491,10 @@ static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
        kfree(amdgpu_fb);
 }
 
-static int amdgpu_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                                 struct drm_file *file_priv,
-                                                 unsigned int *handle)
+static int amdgpu_display_user_framebuffer_create_handle(
+                       struct drm_framebuffer *fb,
+                       struct drm_file *file_priv,
+                       unsigned int *handle)
 {
        struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
 
@@ -498,15 +502,28 @@ static int amdgpu_user_framebuffer_create_handle(struct drm_framebuffer *fb,
 }
 
 static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
-       .destroy = amdgpu_user_framebuffer_destroy,
-       .create_handle = amdgpu_user_framebuffer_create_handle,
+       .destroy = amdgpu_display_user_framebuffer_destroy,
+       .create_handle = amdgpu_display_user_framebuffer_create_handle,
 };
 
-int
-amdgpu_framebuffer_init(struct drm_device *dev,
-                       struct amdgpu_framebuffer *rfb,
-                       const struct drm_mode_fb_cmd2 *mode_cmd,
-                       struct drm_gem_object *obj)
+uint32_t amdgpu_display_framebuffer_domains(struct amdgpu_device *adev)
+{
+       uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
+
+#if defined(CONFIG_DRM_AMD_DC)
+       if (adev->asic_type >= CHIP_CARRIZO && adev->asic_type < CHIP_RAVEN &&
+           adev->flags & AMD_IS_APU &&
+           amdgpu_device_asic_has_dc_support(adev->asic_type))
+               domain |= AMDGPU_GEM_DOMAIN_GTT;
+#endif
+
+       return domain;
+}
+
+int amdgpu_display_framebuffer_init(struct drm_device *dev,
+                                   struct amdgpu_framebuffer *rfb,
+                                   const struct drm_mode_fb_cmd2 *mode_cmd,
+                                   struct drm_gem_object *obj)
 {
        int ret;
        rfb->obj = obj;
@@ -520,9 +537,9 @@ amdgpu_framebuffer_init(struct drm_device *dev,
 }
 
 struct drm_framebuffer *
-amdgpu_user_framebuffer_create(struct drm_device *dev,
-                              struct drm_file *file_priv,
-                              const struct drm_mode_fb_cmd2 *mode_cmd)
+amdgpu_display_user_framebuffer_create(struct drm_device *dev,
+                                      struct drm_file *file_priv,
+                                      const struct drm_mode_fb_cmd2 *mode_cmd)
 {
        struct drm_gem_object *obj;
        struct amdgpu_framebuffer *amdgpu_fb;
@@ -547,7 +564,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
                return ERR_PTR(-ENOMEM);
        }
 
-       ret = amdgpu_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
+       ret = amdgpu_display_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
        if (ret) {
                kfree(amdgpu_fb);
                drm_gem_object_put_unlocked(obj);
@@ -558,7 +575,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
 }
 
 const struct drm_mode_config_funcs amdgpu_mode_funcs = {
-       .fb_create = amdgpu_user_framebuffer_create,
+       .fb_create = amdgpu_display_user_framebuffer_create,
        .output_poll_changed = drm_fb_helper_output_poll_changed,
 };
 
@@ -580,7 +597,7 @@ static const struct drm_prop_enum_list amdgpu_dither_enum_list[] =
        { AMDGPU_FMT_DITHER_ENABLE, "on" },
 };
 
-int amdgpu_modeset_create_props(struct amdgpu_device *adev)
+int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
 {
        int sz;
 
@@ -629,7 +646,7 @@ int amdgpu_modeset_create_props(struct amdgpu_device *adev)
        return 0;
 }
 
-void amdgpu_update_display_priority(struct amdgpu_device *adev)
+void amdgpu_display_update_priority(struct amdgpu_device *adev)
 {
        /* adjustment options for the display watermarks */
        if ((amdgpu_disp_priority == 0) || (amdgpu_disp_priority > 2))
@@ -639,7 +656,7 @@ void amdgpu_update_display_priority(struct amdgpu_device *adev)
 
 }
 
-static bool is_hdtv_mode(const struct drm_display_mode *mode)
+static bool amdgpu_display_is_hdtv_mode(const struct drm_display_mode *mode)
 {
        /* try and guess if this is a tv or a monitor */
        if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
@@ -651,9 +668,9 @@ static bool is_hdtv_mode(const struct drm_display_mode *mode)
                return false;
 }
 
-bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
-                                   const struct drm_display_mode *mode,
-                                   struct drm_display_mode *adjusted_mode)
+bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
+                                       const struct drm_display_mode *mode,
+                                       struct drm_display_mode *adjusted_mode)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_encoder *encoder;
@@ -696,7 +713,7 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                    ((amdgpu_encoder->underscan_type == UNDERSCAN_ON) ||
                     ((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) &&
                      drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) &&
-                     is_hdtv_mode(mode)))) {
+                     amdgpu_display_is_hdtv_mode(mode)))) {
                        if (amdgpu_encoder->underscan_hborder != 0)
                                amdgpu_crtc->h_border = amdgpu_encoder->underscan_hborder;
                        else
@@ -764,10 +781,10 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
  * unknown small number of scanlines wrt. real scanout position.
  *
  */
-int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
-                              unsigned int flags, int *vpos, int *hpos,
-                              ktime_t *stime, ktime_t *etime,
-                              const struct drm_display_mode *mode)
+int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev,
+                       unsigned int pipe, unsigned int flags, int *vpos,
+                       int *hpos, ktime_t *stime, ktime_t *etime,
+                       const struct drm_display_mode *mode)
 {
        u32 vbl = 0, position = 0;
        int vbl_start, vbl_end, vtotal, ret = 0;
@@ -859,7 +876,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
        return ret;
 }
 
-int amdgpu_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc)
+int amdgpu_display_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc)
 {
        if (crtc < 0 || crtc >= adev->mode_info.num_crtc)
                return AMDGPU_CRTC_IRQ_NONE;