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