[PATCH 4/7] drm/amdgpu: simplify encoder and connector setup
Deng, Emily
Emily.Deng at amd.com
Sat Oct 8 08:22:53 UTC 2016
Reviewed-By: Emily Deng <Emily.Deng at amd.com>
> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Alex Deucher
> Sent: Saturday, October 01, 2016 1:09 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher at amd.com>
> Subject: [PATCH 4/7] drm/amdgpu: simplify encoder and connector setup
>
> No need to emulate all of the stuff for real hw.
>
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> drivers/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 decbba5..ff0b55a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> @@ -1504,88 +1504,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,
> @@ -1970,17 +1888,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 29e0ce0..0c8b21e 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; @@ -540,8 +606,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;
> }
> @@ -561,10 +627,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;
> }
>
> @@ -590,45 +652,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) {
> + kfree(connector);
> + 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);
>
> - /* add a new one */
> - amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder),
> GFP_KERNEL);
> - if (!amdgpu_encoder)
> - return;
> + connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
> + if (!connector)
> + return -ENOMEM;
>
> - 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);
> + /* 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);
> +
> + /* link them */
> + drm_mode_connector_attach_encoder(connector, encoder);
> +
> + return 0;
> }
>
> static const struct amdgpu_display_funcs dce_virtual_display_funcs = { @@
> -644,8 +701,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.5.5
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list