drm/amdgpu: simplify encoder and connector setup (v2)
authorAlex Deucher <alexander.deucher@amd.com>
Fri, 30 Sep 2016 16:37:36 +0000 (12:37 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Oct 2016 18:38:06 +0000 (14:38 -0400)
No need to emulate all of the stuff for real hw.

v2: warning fix

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

index e3281d4e3e414cc9d693932911215c6fc7216d6f..3af8ffb45b64d9d26ab885ef3f7eb5f354462ba5 100644 (file)
@@ -1517,88 +1517,6 @@ static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {
        .force = amdgpu_connector_dvi_force,
 };
 
-static struct drm_encoder *
-amdgpu_connector_virtual_encoder(struct drm_connector *connector)
-{
-       int enc_id = connector->encoder_ids[0];
-       struct drm_encoder *encoder;
-       int i;
-       for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
-               if (connector->encoder_ids[i] == 0)
-                       break;
-
-               encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
-               if (!encoder)
-                       continue;
-
-               if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
-                       return encoder;
-       }
-
-       /* pick the first one */
-       if (enc_id)
-               return drm_encoder_find(connector->dev, enc_id);
-       return NULL;
-}
-
-static int amdgpu_connector_virtual_get_modes(struct drm_connector *connector)
-{
-       struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
-
-       if (encoder) {
-               amdgpu_connector_add_common_modes(encoder, connector);
-       }
-
-       return 0;
-}
-
-static int amdgpu_connector_virtual_mode_valid(struct drm_connector *connector,
-                                          struct drm_display_mode *mode)
-{
-       return MODE_OK;
-}
-
-static int
-amdgpu_connector_virtual_dpms(struct drm_connector *connector, int mode)
-{
-       return 0;
-}
-
-static enum drm_connector_status
-
-amdgpu_connector_virtual_detect(struct drm_connector *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-static int
-amdgpu_connector_virtual_set_property(struct drm_connector *connector,
-                                 struct drm_property *property,
-                                 uint64_t val)
-{
-       return 0;
-}
-
-static void amdgpu_connector_virtual_force(struct drm_connector *connector)
-{
-       return;
-}
-
-static const struct drm_connector_helper_funcs amdgpu_connector_virtual_helper_funcs = {
-       .get_modes = amdgpu_connector_virtual_get_modes,
-       .mode_valid = amdgpu_connector_virtual_mode_valid,
-       .best_encoder = amdgpu_connector_virtual_encoder,
-};
-
-static const struct drm_connector_funcs amdgpu_connector_virtual_funcs = {
-       .dpms = amdgpu_connector_virtual_dpms,
-       .detect = amdgpu_connector_virtual_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .set_property = amdgpu_connector_virtual_set_property,
-       .destroy = amdgpu_connector_destroy,
-       .force = amdgpu_connector_virtual_force,
-};
-
 void
 amdgpu_connector_add(struct amdgpu_device *adev,
                      uint32_t connector_id,
@@ -1983,17 +1901,6 @@ amdgpu_connector_add(struct amdgpu_device *adev,
                        connector->interlace_allowed = false;
                        connector->doublescan_allowed = false;
                        break;
-               case DRM_MODE_CONNECTOR_VIRTUAL:
-                       amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
-                       if (!amdgpu_dig_connector)
-                               goto failed;
-                       amdgpu_connector->con_priv = amdgpu_dig_connector;
-                       drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_virtual_funcs, connector_type);
-                       drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_virtual_helper_funcs);
-                       subpixel_order = SubPixelHorizontalRGB;
-                       connector->interlace_allowed = false;
-                       connector->doublescan_allowed = false;
-                       break;
                }
        }
 
index bc8f5e332915eab176c9524ef34727c72d5769db..b981e769603bc505d7526574e86c0a03cb216f82 100644 (file)
@@ -39,6 +39,8 @@
 
 static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
 static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
+static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
+                                             int index);
 
 /**
  * dce_virtual_vblank_wait - vblank wait asic callback.
@@ -274,24 +276,6 @@ 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;
 }
 
@@ -370,38 +354,120 @@ static int dce_virtual_early_init(void *handle)
        return 0;
 }
 
-static bool dce_virtual_get_connector_info(struct amdgpu_device *adev)
+static struct drm_encoder *
+dce_virtual_encoder(struct drm_connector *connector)
 {
-       struct amdgpu_i2c_bus_rec ddc_bus;
-       struct amdgpu_router router;
-       struct amdgpu_hpd hpd;
+       int enc_id = connector->encoder_ids[0];
+       struct drm_encoder *encoder;
+       int i;
+
+       for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+               if (connector->encoder_ids[i] == 0)
+                       break;
+
+               encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+               if (!encoder)
+                       continue;
 
-       /* look up gpio for ddc, hpd */
-       ddc_bus.valid = false;
-       hpd.hpd = AMDGPU_HPD_NONE;
-       /* needed for aux chan transactions */
-       ddc_bus.hpd = hpd.hpd;
+               if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
+                       return encoder;
+       }
 
-       memset(&router, 0, sizeof(router));
-       router.ddc_valid = false;
-       router.cd_valid = false;
-       amdgpu_display_add_connector(adev,
-                                     0,
-                                     ATOM_DEVICE_CRT1_SUPPORT,
-                                     DRM_MODE_CONNECTOR_VIRTUAL, &ddc_bus,
-                                     CONNECTOR_OBJECT_ID_VIRTUAL,
-                                     &hpd,
-                                     &router);
+       /* pick the first one */
+       if (enc_id)
+               return drm_encoder_find(connector->dev, enc_id);
+       return NULL;
+}
+
+static int dce_virtual_get_modes(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_display_mode *mode = NULL;
+       unsigned i;
+       static const struct mode_size {
+               int w;
+               int h;
+       } common_modes[17] = {
+               { 640,  480},
+               { 720,  480},
+               { 800,  600},
+               { 848,  480},
+               {1024,  768},
+               {1152,  768},
+               {1280,  720},
+               {1280,  800},
+               {1280,  854},
+               {1280,  960},
+               {1280, 1024},
+               {1440,  900},
+               {1400, 1050},
+               {1680, 1050},
+               {1600, 1200},
+               {1920, 1080},
+               {1920, 1200}
+       };
+
+       for (i = 0; i < 17; i++) {
+               mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
+               drm_mode_probed_add(connector, mode);
+       }
 
-       amdgpu_display_add_encoder(adev, ENCODER_VIRTUAL_ENUM_VIRTUAL,
-                                                       ATOM_DEVICE_CRT1_SUPPORT,
-                                                       0);
+       return 0;
+}
 
-       amdgpu_link_encoder_connector(adev->ddev);
+static int dce_virtual_mode_valid(struct drm_connector *connector,
+                                 struct drm_display_mode *mode)
+{
+       return MODE_OK;
+}
 
-       return true;
+static int
+dce_virtual_dpms(struct drm_connector *connector, int mode)
+{
+       return 0;
 }
 
+static enum drm_connector_status
+dce_virtual_detect(struct drm_connector *connector, bool force)
+{
+       return connector_status_connected;
+}
+
+static int
+dce_virtual_set_property(struct drm_connector *connector,
+                        struct drm_property *property,
+                        uint64_t val)
+{
+       return 0;
+}
+
+static void dce_virtual_destroy(struct drm_connector *connector)
+{
+       drm_connector_unregister(connector);
+       drm_connector_cleanup(connector);
+       kfree(connector);
+}
+
+static void dce_virtual_force(struct drm_connector *connector)
+{
+       return;
+}
+
+static const struct drm_connector_helper_funcs dce_virtual_connector_helper_funcs = {
+       .get_modes = dce_virtual_get_modes,
+       .mode_valid = dce_virtual_mode_valid,
+       .best_encoder = dce_virtual_encoder,
+};
+
+static const struct drm_connector_funcs dce_virtual_connector_funcs = {
+       .dpms = dce_virtual_dpms,
+       .detect = dce_virtual_detect,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .set_property = dce_virtual_set_property,
+       .destroy = dce_virtual_destroy,
+       .force = dce_virtual_force,
+};
+
 static int dce_virtual_sw_init(void *handle)
 {
        int r, i;
@@ -430,16 +496,16 @@ static int dce_virtual_sw_init(void *handle)
        adev->ddev->mode_config.max_width = 16384;
        adev->ddev->mode_config.max_height = 16384;
 
-       /* allocate crtcs */
+       /* allocate crtcs, encoders, connectors */
        for (i = 0; i < adev->mode_info.num_crtc; i++) {
                r = dce_virtual_crtc_init(adev, i);
                if (r)
                        return r;
+               r = dce_virtual_connector_encoder_init(adev, i);
+               if (r)
+                       return r;
        }
 
-       dce_virtual_get_connector_info(adev);
-       amdgpu_print_display_setup(adev->ddev);
-
        drm_kms_helper_poll_init(adev->ddev);
 
        adev->mode_info.mode_config_initialized = true;
@@ -536,8 +602,8 @@ static void dce_virtual_encoder_commit(struct drm_encoder *encoder)
 
 static void
 dce_virtual_encoder_mode_set(struct drm_encoder *encoder,
-                     struct drm_display_mode *mode,
-                     struct drm_display_mode *adjusted_mode)
+                            struct drm_display_mode *mode,
+                            struct drm_display_mode *adjusted_mode)
 {
        return;
 }
@@ -557,10 +623,6 @@ static bool dce_virtual_encoder_mode_fixup(struct drm_encoder *encoder,
                                    const struct drm_display_mode *mode,
                                    struct drm_display_mode *adjusted_mode)
 {
-
-       /* set the active encoder to connector routing */
-       amdgpu_encoder_set_active_device(encoder);
-
        return true;
 }
 
@@ -586,45 +648,40 @@ static const struct drm_encoder_funcs dce_virtual_encoder_funcs = {
        .destroy = dce_virtual_encoder_destroy,
 };
 
-static void dce_virtual_encoder_add(struct amdgpu_device *adev,
-                                uint32_t encoder_enum,
-                                uint32_t supported_device,
-                                u16 caps)
+static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
+                                             int index)
 {
-       struct drm_device *dev = adev->ddev;
        struct drm_encoder *encoder;
-       struct amdgpu_encoder *amdgpu_encoder;
-
-       /* see if we already added it */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               amdgpu_encoder = to_amdgpu_encoder(encoder);
-               if (amdgpu_encoder->encoder_enum == encoder_enum) {
-                       amdgpu_encoder->devices |= supported_device;
-                       return;
-               }
+       struct drm_connector *connector;
 
+       /* add a new encoder */
+       encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL);
+       if (!encoder)
+               return -ENOMEM;
+       encoder->possible_crtcs = 1 << index;
+       drm_encoder_init(adev->ddev, encoder, &dce_virtual_encoder_funcs,
+                        DRM_MODE_ENCODER_VIRTUAL, NULL);
+       drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs);
+
+       connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
+       if (!connector) {
+               kfree(encoder);
+               return -ENOMEM;
        }
 
-       /* add a new one */
-       amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder), GFP_KERNEL);
-       if (!amdgpu_encoder)
-               return;
+       /* add a new connector */
+       drm_connector_init(adev->ddev, connector, &dce_virtual_connector_funcs,
+                          DRM_MODE_CONNECTOR_VIRTUAL);
+       drm_connector_helper_add(connector, &dce_virtual_connector_helper_funcs);
+       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+       connector->interlace_allowed = false;
+       connector->doublescan_allowed = false;
+       drm_connector_register(connector);
 
-       encoder = &amdgpu_encoder->base;
-       encoder->possible_crtcs = 0x1;
-       amdgpu_encoder->enc_priv = NULL;
-       amdgpu_encoder->encoder_enum = encoder_enum;
-       amdgpu_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-       amdgpu_encoder->devices = supported_device;
-       amdgpu_encoder->rmx_type = RMX_OFF;
-       amdgpu_encoder->underscan_type = UNDERSCAN_OFF;
-       amdgpu_encoder->is_ext_encoder = false;
-       amdgpu_encoder->caps = caps;
-
-       drm_encoder_init(dev, encoder, &dce_virtual_encoder_funcs,
-                                        DRM_MODE_ENCODER_VIRTUAL, NULL);
-       drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs);
-       DRM_INFO("[FM]encoder: %d is VIRTUAL\n", amdgpu_encoder->encoder_id);
+       /* link them */
+       drm_mode_connector_attach_encoder(connector, encoder);
+
+       return 0;
 }
 
 static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
@@ -640,8 +697,8 @@ static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
        .hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
        .page_flip = &dce_virtual_page_flip,
        .page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
-       .add_encoder = &dce_virtual_encoder_add,
-       .add_connector = &amdgpu_connector_add,
+       .add_encoder = NULL,
+       .add_connector = NULL,
        .stop_mc_access = &dce_virtual_stop_mc_access,
        .resume_mc_access = &dce_virtual_resume_mc_access,
 };