From 66264ba80492571d9177158f2989e267a591507b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 30 Sep 2016 12:37:36 -0400 Subject: [PATCH] drm/amdgpu: simplify encoder and connector setup (v2) No need to emulate all of the stuff for real hw. v2: warning fix Reviewed-By: Emily Deng Signed-off-by: Alex Deucher --- .../gpu/drm/amd/amdgpu/amdgpu_connectors.c | 93 ------- drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 231 +++++++++++------- 2 files changed, 144 insertions(+), 180 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index e3281d4e3e41..3af8ffb45b64 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -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; } } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index bc8f5e332915..b981e769603b 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c @@ -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, }; -- 2.20.1